Выберите объекты, где у всех детей нет внуков
У меня есть следующая трехуровневая иерархия моделей:
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, и у меня есть Squeel; но я согласен на сырой SQL.
Бонусные баллы, если вы можете дать мне все Parent
объекты, для которых все children
не иметь grandchildren
и все children
иметь my_number < 5
,
1 ответ
После небольшого исследования я думаю, что я получил решение с помощью group
а также having
статьи.
Вы можете добавить эту область к вашему Parent
модель. Обратите внимание, что нам нужно вручную определить joins
для того, чтобы использовать LEFT JOIN
вместо по умолчанию INNER JOIN
Rails генерирует. Более подробная информация о SQL JOINS здесь.
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
атрибут хранится в БД, вы можете сделать:
Parent.with_children_having_no_grand_children.where(children: { my_number: 5 }))