选择所有孩子都没有孙子的对象

时间:2015-02-18 13:17:35

标签: sql ruby-on-rails-3 squeel

我有以下三级模型层次结构:

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没有children的所有grandchildren个对象。我怎样才能做到这一点?我更喜欢Rails-way,而且我有可用的吱吱声;但我会满足于原始SQL。

如果您可以向我提供所有Parent所有children 所有grandchildren {{}> {{ {1}}。

1 个答案:

答案 0 :(得分:1)

经过一些研究后,我认为我使用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 }))