根据其子级的属性(或没有子级)对Rails进行范围筛选
根据其子级的属性(或没有子级)对Rails进行范围筛选
我有两个模型:Sophead
和SopheadIssue
。
SopheadIssue属于Sophead
,
Sophead有多个SopheadIssues
(可选)。
我想在Sophead模型上创建一个范围,用于匹配以下两个条件之一的Sopheads:
- Sophead没有任何SopheadIssues
- Sophead没有SopheadIssue属性为(active=true)的SopheadIssues。
目前我尝试了以下方法:
scope :no_issue, -> { joins(:sophead_issues).where.not("active = ?", true) }
但是这并不起作用,因为它缺少没有任何SopheadIssues的Sopheads。
非常感谢任何帮助。
非常感谢!
问题出现的原因是joins
是INNER JOIN
,它会过滤掉没有sophead_issues
的sophead
。解决方法是使用left_joins:
scope :no_issue, -> { left_joins(:sophead_issues).where("sophead_issues.active != ? OR sophead_issues.sophead_id IS NULL", true) }
问题的原因是joins
使用的是INNER JOIN
,它只会返回有关联的记录,而过滤掉了没有sophead_issues
的sophead
记录。解决方法是使用left_joins
,它会返回所有sophead
记录,包括没有sophead_issues
的记录。具体的解决方法如下所示:
scope :no_issue, -> { left_joins(:sophead_issues).where("sophead_issues.active != ? OR sophead_issues.sophead_id IS NULL", true) }
Rails scope according to an attribute of its child (or having no children)
问题出现的原因:
这个问题是关于在Rails中根据其子对象的属性来定义一个scope的。根据给出的代码,可以看出有三个scope:active、no_associations和no_issue。active scope是根据sophead_issues表中的active属性来筛选数据。no_associations scope是找出没有关联子对象的sopheads。no_issue scope是将active和no_associations两个scope结合起来,返回符合条件的结果。
解决方法:
可以将这些scope定义为类方法,或者将它们链式调用形成一个scope,具体取决于个人的偏好。
代码如下:
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 }
以上就是根据子对象属性来定义Rails scope的方法,希望能对你有所帮助。