[英]ActiveRecord Rails How do you query for an associated model in a polymorphic association
I have a polymorphic association on my PartnerItem
model :我的
PartnerItem
模型上有一个多态关联:
class PartnersItem < ApplicationRecord
belongs_to :item, polymorphic: true
belongs_to :partner
end
Item can be a program
or a session
项目可以是
program
或session
Program
is also linked to sessions
in a has_many
relationship : Program has_many Sessions
Program
还以has_many
关系链接到sessions
: Program has_many Sessions
I need to find all Programs
to which a partner_item
is linked.我需要找到
partner_item
链接到的所有Programs
。 That means这意味着
Any program
/ item
associated to a specific partner与特定合作伙伴关联的任何
program
/ item
Any program
linked to a session/item
associated to a specific partner.链接到与特定合作伙伴关联的
session/item
任何program
。
Finally the query results need to be unique, meaning a Program
can't appear twice in the results最后查询结果必须是唯一的,这意味着一个
Program
不能在结果中出现两次
I am having a hard time figuring out how to assemble such query.我很难弄清楚如何组合这样的查询。
This retrieves all items
for a specific partner
but Im stuck on what are the next steps这将检索特定
partner
所有items
,但我坚持下一步是什么
PartnerItem.where(
partner: current_partner
).items
One way to do could be like this:一种方法可能是这样的:
program_ids = PartnerItem.where(partner: current_partner, item_type: 'Program').pluck(:item_id)
program_ids += Session.joins(:partner_items).where(partner_items: { partner_id: partner.id }).where.not(program_id: nil).pluck(:program_id)
Program.where(id: program_ids.uniq)
This would probably return all the Program
records which have a PartnerItem
directly or through Session
.这可能会直接或通过
Session
返回所有具有PartnerItem
的Program
记录。
partner_items = PartnerItem.where(partner: current_partner) problem_ids = partner_items.filter { |x| x.item_type == "Program" }.map(&:item_id) session_ids = partner_items.filter { |x| x.item_type == "Session" }.map(&:item_id) Problem.joins(:sessions) .where("problems.id IN (?) OR sessions.id IN (?)", problem_ids, session_ids) .distinct
If I understand correctly, this is almost what you:如果我理解正确,这几乎就是你:
current_partner.partners_items
want except then you get models with a reference to the program or to the session and when the session you want the program it belongs to.想要除此之外,您会获得包含对程序或会话的引用的模型,以及您希望该程序所属的会话的时间。
In SQL this would be:在 SQL 中,这将是:
SELECT programs.*
FROM programs
INNER JOIN partners
ON partners.item_type = 'Program' and partners.item_id = programs.id
WHERE partners.id = ?
UNION
SELECT programs.*
FROM programs
INNER JOIN sessions
ON sessions.program_id = programs.id
INNER JOIN partners
ON sessions.item_type = 'Session' and partners.item_id = sessions.id
WHERE partners.id = ?
Because the joins have a different structure the SQL is going to need a UNION or a subquery which is hard to express in one query using ActiveRecord.因为连接具有不同的结构,所以 SQL 将需要一个 UNION 或一个子查询,这在使用 ActiveRecord 的查询中很难表达。
First I would add scopes for the polymorphic types.首先,我会为多态类型添加作用域。
class PartnersItem < ApplicationRecord
belongs_to :item, polymorphic: true
belongs_to :partner
scope :programs, -> { where(type: 'Program') }
scope :sessions, -> { where(type: 'Session') }
end
Then you might query for the program ids and the session ids for the current partner and use that in the final query.然后,您可以查询当前合作伙伴的程序 ID 和会话 ID,并在最终查询中使用它们。
partner_program_ids = current_partner.partners_items.programs.pluck(:id)
partner_session_ids = current_partner.partners_items.sessions.pluck(:id)
Program.joins(:session)
.where("programs.id = :partner_program_ids
OR sessions.id = :partner_session_ids",
partner_program_ids: partner_program_ids,
partner_session_ids: partner_session_ids)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.