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.

经过一些研究,我认为我通过使用 grouphaving 子句找到了解决方案。

您可以将此范围添加到您的 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 }))