我有2个模型:Sophead
和SopheadIssue
。
SopheadIssue belongs to Sophead
,
Sophead has many SopheadIssues
(可选)。
我想在Sophead模型上为与以下两个条件均匹配的Sopheads创建范围:
此刻我已经尝试了以下方法:
scope :no_issue, -> { joins(:sophead_issues).where.not("active = ?", true) }
但是这不起作用,因为它缺少没有任何SopheadIssues的Sophead。
非常感谢任何帮助。
非常感谢!
答案 0 :(得分:3)
问题在于joins
是INNER JOIN
,它过滤掉了sophead
而没有sophead_issues
。您需要在此处使用left_joins:
scope :no_issue, -> { left_joins(:sophead_issues).where("sophead_issues.active != ? OR sophead_issues.sophead_id IS NULL", true) }
答案 1 :(得分:0)
尽管目前无法测试和确认,但我认为以下方法应该可以工作:
scope :active, -> { joins(:sophead_issues).where.not(sophead_issues: { active: true }) }
scope :no_associations, -> { joins(:sophead_issues).where.not(sophead_issues: { sophead_id: nil }) }
scope :no_issue, -> { active.no_associations }) }
出于我自身的理智,我将其分解为几个查询,尽管我可以进行测试,但我想您应该可以使用or
和not
将它们组合在一起。但是,我不确定如何在不进行一点测试的情况下实现它。
基本上,active
范围是不言自明的:您发现sophead_issues
的{{1}}设置为active
的情况。
true
您的no_associations
没有关联。如果您有兴趣,请进一步了解here。
最后,sopheads
将两种方法结合起来,返回您的收藏夹。
您可以根据自己的喜好将其重构为一个类方法,或两个链接形成范围的类方法。
编辑:或者使用@IgorDrozdov的方法,它会更清洁:)(除非您是