高级 (nexted) has_many :通过 Ruby on Rails 中的查询(双连接)

发布于 2024-11-04 04:43:19 字数 2488 浏览 0 评论 0原文

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

现在,我完全可以通过原始 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 关系,这就是我需要建议的地方。

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

在这里,我什至无法以 ruby​​ 方式表达这种关系,我必须通过以下方式解决它:

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

我很感激任何形式的建议,以及 预先非常感谢, 克里斯蒂安·帕帕特.

I am having a somewhat too nested database layout, however, I seem to need it. That is, Our website visitors may each have a single account with maintaining multiple users (think of identities) within.
Now they may create tickets, which are grouped by ticket sections, and we have ticket manager (operator) to process the incoming tickets.
Not every ticket manager may see every ticket but only those this manager is a member of the given ticket section for.

Now, I am totally fine in querying via raw SQL statements, but I failed to verbalizing those two special queries the Rails way.

Here is the (abstract) model:

# 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

I am aware of basic has_many :through-constructs, however, here, I am accessing more than three tables to get the tickets.

Something that actually works for in the User's model is:

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

Here I am using a helper relation (managing_relations), which is absolutely never used except by the two has_many relations below.
I were not able to describe a User.managing_sections nor User.managing_tickets relation without this helper, which is, where I need an advice for.

Secondly, the customer is to have a look at all of the tickets he can manage on any User (think of an identity) he has logged in, so what I need, is a way to collect all tickets (/sections) this Account is permitted to manage (identified by being a member of the corresponding TicketSection)

Here I even were not able to express this relation the ruby way, and I had to work around it by the following:

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

I'd appreciate any kind of advice, and
many thanks in advance,
Christian Parpart.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文