高级(嵌套)has_many:通过Ruby on Rails中的查询(双JOIN)

时间:2011-04-29 04:57:11

标签: ruby-on-rails ruby-on-rails-3 activerecord

我有一个太嵌套的数据库布局,但是,我似乎需要它。也就是说,我们的网站访问者可能都拥有一个帐户,可以在其中维护多个用户(想到身份)。 现在,他们可以创建票证,按票证部分分组,我们有票务管理员(操作员)来处理传入的票证。 并非每个票务经理都可以看到每个票证,但只有那个经理才能看到给定票证部分的成员。

现在,我完全可以通过原始SQL语句进行查询,但是我没有用Rails的方式用语言表达这两个特殊查询。

这是(摘要)模型:

# account system
class Account < ActiveRecord::Base
  has_many :users
  has_many :tickets, :through => :users
  has_many :managing_ticket_sections, ... # TicketSection-collection this account (any of its users) is operate for
  has_many :managing_tickets, ...         # Ticket-collection this account (any of its users) may operate on
end

class User < ActiveRecord::Base
  belongs_to :account
  has_many :tickets
  has_many :managing_ticket_sections, ... # TicketSection-collection this user is operate for
  has_many :managing_tickets, ...         # Ticket-collection this user may operate on
end

# ticket system
class Ticket < ActiveRecord::Base
  belongs_to :author, :class_name => "User"
  belongs_to :assignee, :class_name => "User"
  belongs_to :section, :class_name => "TicketSection"
end

class TicketSection < ActiveRecord::Base
  has_many :tickets
  has_many :operators
end

class TicketSectionManager < ActiveRecord::Base
  belongs_to :manager, :class_name => "User"
  belongs_to :section
end

我知道基本的has_many :through - 构造,但是,在这里,我正在访问三个以上的表来获取票证。

用户模型中实际适用的东西是:

class User < ActiveRecord::Base
  has_many :managing_relations, :class_name => "TicketSectionManager" # XXX some kind of helper, for the two below
  has_many :managing_sections, :class_name => "TicketSection", :through => :managing_relations, :source => :section
  has_many :managing_tickets, :class_name => "Ticket", :through => :managing_relations, :source => :section
end

这里我使用的是辅助关系(managing_relations),除了下面的两个has_many关系外,绝对不会使用它。 没有这个帮助器,我无法描述User.managing_sections和User.managing_tickets关系,这是我需要建议的地方。

其次,客户要查看他可以在任何用户(想到身份)上登记的所有门票,所以我需要的是一种方法收集此帐户被允许管理的所有票证(/部分)(通过成为相应的TicketSection成员)

在这里,我甚至无法以红宝石的方式表达这种关系,我不得不通过以下方式解决这个问题:

class Account
  def managing_tickets
    Ticket.find_by_sql("SELECT t.* FROM tickets AS t
        INNER JOIN ticket_section_managers AS m ON m.section_id = t.section_id
        INNER JOIN users AS u ON u.id = m.user_id
        WHERE u.account_id = #{id}")
  end
end

我很感激任何建议,并且 提前谢谢了, Christian Parpart。

0 个答案:

没有答案