2010-07-07 22 views
0

Je les tableaux suivants:MySQL/Ruby on Rails - Comment "SUM" dans: has_many cas

Utilisateur: has_many Achats
Article: has_many Achats

article a une colonne "montant" (peut être + ou -) et je dois trouver tous les utilisateurs qui ont une somme positive de "Item.amounts" (sur tous les achats que chacun a fait).

A quoi ressemble cette requête? (Je ne suis pas sûr de savoir comment gérer "SUM" correctement, dans ce cas.)

J'ai commencé avec ce qui suit, mais évidemment, c'est faux ... (il ne comprendrait pas les achats qui ont un point négatif avec un Item.amount ...)

@users = User.find (: tous,
: include => {: achats =>: item},
: select => « SOMME (item.amount) "
: order =>" ... "
: conditions =>" ... ",
: group => "users.id",
: ayant => "SUM (item.amount)> 0" )

Merci pour votre aide avec ça!
Tom

Répondre

1

Essayez ceci:

User.all(:joins => items, :group => "users.id", 
      :having => "SUM(items.amount) > 0") 
+0

Merci - cela fonctionne au besoin! 1 question précédente: quelle est l'explication que cela fonctionne avec ": jointures" mais pas avec ": include"? – TomDogg

+0

La clause ': include' utilise' LEFT OUTER JOIN', ce qui entraîne des montants NULL pour les utilisateurs sans éléments. La fonction SUM n'aime pas NULL. En dehors de cela, dans cette situation ': joins' est plus approprié que': include'. –

+0

Super, merci beaucoup! – TomDogg

0

Il semble que ce soit un bon cas pour certaines méthodes de modélisation.

Je n'ai pas testé, mais je pense que vous voulez faire quelque chose de semblable à ce qui suit:

class User < ActiveRecord::Base 

has_many :purchases 
has_many :items, :through => :purchases 

def items_total 
    #get all the items iterate over them to get the amount, 
    #compact to get rid of nils 
    #and reduce with a sum function to total and return 
    items.all.each{|item| item.amount}.compact.reduce(:+) 
end 

puis

User.items_total

+0

Merci , mais si je ne me trompe pas, il semble y avoir un malentendu: votre solution semble retourner une somme besoin des utilisateurs pour les "conditions" mentionnées). Btw, je n'ai jamais rencontré ".reduce (: +)" - une idée où je peux trouver la documentation pour celui-ci? – TomDogg

+0

oui, vous avez raison, je pensais que vous cherchiez le total des articles pour un utilisateur, dans un contexte de «grand total». reduce (: +) est un raccourci pour réduire {| sum, i | sum + i} qui résume tous les éléments d'une collection. http://apidock.com/ruby/Enumerable/reduce –

+0

Cool, merci beaucoup! – TomDogg