2017-10-10 2 views
0

J'essaye de commander une liste de magasins par le nombre de produits de l'intérieur dans chaque magasin. J'ai une jointure entre le magasin et le produit qui est la propriété. Donc, mes modèles ressemblent:Trier les magasins par leur nombre de produits dans les rails

shop.rb

has_many :ownerships 
has_many :products, through: :ownerships 

product.rb

has_many :ownerships 
has_many :shops, through: :ownerships 

ownership.rb

belongs_to :product 
belongs_to :shop 

Comment puis-je transformer cette requête autour d'ordonner la produits en nombre?

@shops = Shop.all.includes(:products).where('products.id IS NOT NULL').references(:products).order(id :desc) 

J'ai essayé des variations de .group('id').order('count(*) DESC') telles que:

@shops = Shop.all.includes(:products).where('products.id IS NOT NULL').references(:products).group(:id).order('count(*) DESC') 

Mais ne semblent contourner des erreurs comme

ActiveRecord::StatementInvalid: PG::GroupingError: ERROR: column "products.id" must appear in the GROUP BY clause or be used in an aggregate function 
+3

Copie possible de [Rails 3. Ordre par nombre de correspondances (plusieurs à plusieurs)] (https://stackoverflow.com/questions/16834399/rails-3-order-by-count-of-matches-many- to-many) – Genzume

+0

Ce qui précède me donne le même PG :: GroupingError. Utiliser 'Shop.all.sort_by {| s | s.products.count} 'fonctionne réellement, mais est plutôt lent. – albaba

+0

Compte de quoi? Le nombre de produits uniques ou le nombre total d'inventaire de tous les produits ou même le nombre d'un produit spécifique? – max

Répondre

0

Je l'ai essayé sur mon site, je pense nous ce problème juste à cause de groupe PG par s'il vous plaît essayez ceci:

Shop.all.joins(:products).select('products.*').where.not(products: {id: nil}).references(:products).group('products.id') 
+0

Ceci est si proche, cependant, cela semble ordonner les produits, pas les instances, ce qui est bizarre, car il revient comme '# albaba

0

Compris ceci au cas où quelqu'un tomberait sur la même chose.

Toutes les réponses/commentaires étaient super proche, mais pour obtenir les magasins classés par ceux qui avaient le plus de produits dans l'ordre décroissant, j'ai utilisé:

@stores = Store.joins(:products).group('stores.id').order('count(products.id) desc') 

En essayant de trouver les magasins avaient la plupart des produits d'une marque particulière classées par ordre décroissant, j'ai modifié ci-dessus à utiliser:

@stores = Store.joins(:products).group('stores.id').where(:products => { :brand_id => @brand.id }).order('count(products.brand_id) desc') 

ActiveRecord FTW.