3
votes

Rails: trouvez tous les parents avec tous les enfants ayant un attribut particulier

J'ai besoin de trouver tous les parents qui ont TOUS les enfants avec un statut = 1.

Si l'un des enfants n'a pas le statut = 1; alors le parent n'est pas sélectionné.

Parent.left_outer_joins(:children).where("children.status = ?", 1)

J'ai essayé ceci, mais cela ne fonctionne pas.

class Parent
  has_many :children
end

class Child
  status = [ 0, 1 ]
end

Cela ne fonctionne pas car j'ai toujours le statut Parent avec enfants = 0


5 commentaires

qu'est-ce que vous entendez par cela ne fonctionne pas. avez-vous rencontré une erreur ou un problème avec cette requête?


@Gabbar Cela ne fonctionne pas car je reçois toujours le statut Parent avec enfants = 0


est status enum?


@Gabbar oui c'est enum


Rejoindre n'est pas suffisant dans votre cas, je suppose. "Tous les enfants ont le statut 1" équivaut à "Il n'y a pas d'enfants avec le statut 0". Vous avez donc besoin d'une requête comme select * from parents p where not exist (select 1 from children c where c.parent_id = p.id and status = 0) - je ne sais pas s'il est possible de le construire avec Interface de requête AR. La magie AREL pourrait peut-être aider, mais pour être honnête dans la pratique, je préfère le SQL pur - car plus lisible et plus simple ...


3 Réponses :


-1
votes

Je pense que vous pourriez faire quelque chose comme ceci:

Parent.joins(:children).where.not(
  id: Child.where(status: :closed).select('DISTINCT "parent_id"')
).distinct


1 commentaires

Mais cela ne montre pas seulement aux parents où tous les enfants sont fermés. Si l'un des enfants est fermé, le parent apparaîtra ici.



0
votes

Je pense que vous aurez besoin d'une sous-requête:

Parent.where.not(id: Children.where.not(status: 1).select(:parent_id))


1 commentaires

Je viens de mettre à jour ma réponse car elle était incorrecte. N'hésitez pas à essayer celui-ci à la place :))



0
votes

Essayez ceci:

Parent.where("id NOT IN (SELECT DISTINCT(parent_id) FROM children WHERE children.status =1)")

J'espère que vous trouverez cela utile !!!


0 commentaires