MySQL / Ruby on Rails - Как да SUM в случай :has_many

Имам следните таблици:

Потребител :has_many покупки
Артикул :has_many покупки

Елементът има колона „сума“ (може да бъде + или -) и трябва да намеря всички потребители, които имат положителна СУМА от „Суми на артикул“ (за всички покупки, които всеки е направил).

Как изглежда това запитване? (Не съм сигурен как да боравя правилно с „SUM“ в този случай.)

Започнах със следното, но очевидно е грешно... (няма да "включи" покупки, които имат артикул с отрицателна сума на артикул...)

@users = User.find(:all,
:include => {:purchases => :item},
:select => "SUM(item.amount)",
:order => " ...",
:conditions => "...",
:group => "users.id",
:having => "SUM(item.amount) > 0")

Благодаря за помощта ви с това!
Том


person TomDogg    schedule 07.07.2010    source източник


Отговори (2)


Опитайте тази:

User.all(:joins => items, :group => "users.id", 
          :having => "SUM(items.amount) > 0")
person Harish Shetty    schedule 07.07.2010
comment
Благодаря - това работи според нуждите! 1 въпрос назад: какво е обяснението, че работи с :joins, но не и с :include? - person TomDogg; 08.07.2010
comment
Клаузата :include използва LEFT OUTER JOIN, което води до NULL суми за потребители без елементи. Функцията SUM не харесва NULL. Освен това в тази ситуация :joins е по-подходящо от :include. - person Harish Shetty; 08.07.2010

Изглежда, че това е добър случай за някои модели методи.

Не съм тествал това, но мисля, че искате да направите нещо подобно на следното:

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

тогава

User.items_total

person Jed Schneider    schedule 07.07.2010
comment
Благодаря, но ако не греша, изглежда има недоразумение: Вашето решение изглежда връща сума (всъщност имам нужда от Потребителите за споменатите условия). Между другото, никога не съм срещал .reduce(:+) - някаква идея къде мога да намеря документацията за този? - person TomDogg; 08.07.2010
comment
да, прав си, мислех, че търсиш общата сума на елементите за потребител в контекст тип „обща сума“. намали(:+) е съкратено за намаляване{|сума, i| sum+i}, което основно сумира всички елементи в колекция. apidock.com/ruby/Enumerable/reduce - person Jed Schneider; 08.07.2010