Étant donné deux modèles ActiveRecord:Comment compter les enregistrements de sous-requête dans la clause where en utilisant ActiveRecord?
class Foo < ApplicationRecord
has_many :bars
end
class Bar < ApplicationRecord
belongs_to :foo
end
avec Bar
ayant un attribut color
avec des valeurs possibles red
et green
, je voudrais obtenir le foos
, qui ont plus rouge bars
, que le vert bars
.
Jusqu'à présent, j'ai pu cette achive comme ceci:
red_bars_sql = Bar.select('COUNT(*)').where(color: 'red').where('foo.id = bar.foo_id').to_sql
green_bars_sql = Bar.select('COUNT(*)').where(color: 'green').where('foo.id = bar.foo_id').to_sql
Foo.where("(#{red_bars_sql}) > (green_bars_sql)")
Ceci effectue assez bien.
Je voudrais savoir s'il existe une autre approche à ce problème. En outre, est-il pour mettre en œuvre cette approche actuelle avec moins de SQL et plus ActiveRecord (éviter le hack de interpolant sql dans la clause where
de Foo
).
J'ai essayé quelque chose le long des lignes:
class Foo < ApplicationRecord
has_many :bars
has_many :reds, -> { reds }, class_name: 'Bar'
has_many :greens, -> { greens }, class_name: 'Bar'
end
class Bar < ApplicationRecord
belongs_to :foo
scope :reds, -> { where(color: 'red') }
scope :greens, -> { where(color: 'green') }
end
puis essayé de regroupement (Foo.joins(:reds, :greens).group(...).having(...)
), mais je ne construit correctement et il ne fonctionne pas.
C'est exactement ce que je cherchais. Merci beaucoup! :) –