Select objects 其中所有 children 都没有 grandchildren
Select objects where all children have no grandchildren
我有以下 three-level 模型层次结构:
class Parent < AR::Base
has_many :children
end
class Child < AR::Base
has_many :grandchildren
belongs_to :parent
attr_accessible :my_number
end
class Grandchild < AR::Base
belongs_to :child
end
预计所有 Parent
都会有多个 children
,但每个 Child
可能有也可能没有任何 grandchildren
。
我想检索所有 Parent
objects 而所有 children
都没有 grandchildren
。我怎样才能做到这一点?我更喜欢 Rails-way,而且我有可用的 squeel;但我会满足于原始 SQL.
如果你能给我所有 Parent
objects 的奖励积分,所有 children
都没有 grandchildren
和 所有 children
都有 my_number < 5
.
经过一些研究,我认为我通过使用 group
和 having
子句找到了解决方案。
您可以将此范围添加到您的 Parent
模型中。请注意,我们需要手动定义 joins
以便使用 LEFT JOIN
而不是默认的 INNER JOIN
Rails 生成。有关 SQL JOINS here.
的更多信息
class Parent < AR::Base
scope :with_children_having_no_grand_children, -> {
joins("LEFT JOIN `children` ON `children`.`parent_id` = `parents`.`id`
LEFT JOIN `grand_children` ON `grand_children`.`child_id` = `children`.`id`")
.group('parents.id')
.having('COUNT(grand_children.id) = 0 AND COUNT(children.id) > 0')
}
end
然后你可以使用:
Parent.with_children_having_no_grand_children
对于第二个问题,假设:my_number
是一个存储在DB中的属性,可以这样:
Parent.with_children_having_no_grand_children.where(children: { my_number: 5 }))
我有以下 three-level 模型层次结构:
class Parent < AR::Base
has_many :children
end
class Child < AR::Base
has_many :grandchildren
belongs_to :parent
attr_accessible :my_number
end
class Grandchild < AR::Base
belongs_to :child
end
预计所有 Parent
都会有多个 children
,但每个 Child
可能有也可能没有任何 grandchildren
。
我想检索所有 Parent
objects 而所有 children
都没有 grandchildren
。我怎样才能做到这一点?我更喜欢 Rails-way,而且我有可用的 squeel;但我会满足于原始 SQL.
如果你能给我所有 Parent
objects 的奖励积分,所有 children
都没有 grandchildren
和 所有 children
都有 my_number < 5
.
经过一些研究,我认为我通过使用 group
和 having
子句找到了解决方案。
您可以将此范围添加到您的 Parent
模型中。请注意,我们需要手动定义 joins
以便使用 LEFT JOIN
而不是默认的 INNER JOIN
Rails 生成。有关 SQL JOINS here.
class Parent < AR::Base
scope :with_children_having_no_grand_children, -> {
joins("LEFT JOIN `children` ON `children`.`parent_id` = `parents`.`id`
LEFT JOIN `grand_children` ON `grand_children`.`child_id` = `children`.`id`")
.group('parents.id')
.having('COUNT(grand_children.id) = 0 AND COUNT(children.id) > 0')
}
end
然后你可以使用:
Parent.with_children_having_no_grand_children
对于第二个问题,假设:my_number
是一个存储在DB中的属性,可以这样:
Parent.with_children_having_no_grand_children.where(children: { my_number: 5 }))