2013-03-26 25 views
9

Mam następującą konfigurację.Grupowanie tablicy i otrzymywanie sumy

Invoice has_many Jobs has_many Tasks belongs_to user 

Chcę uzyskać wszystkie User s z Invoice które mają zadania i podsumować ich ilości

class Invoice < ActiveRecord::Base 
    has_many :jobs 
end 

class Job < ActiveRecord::Base 
    belongs_to :invoice 
    has_many :tasks  
end 

class Task < ActiveRecord::Base 
    belongs_to :job     
    belongs_to :user  
end  

Oto co mam

@invoice = Invoice.find(params[:id]) 
jobs = @invoice.jobs.joins(:tasks) 
     .select('tasks.user_id, (sum(tasks.quantity)*jobs.price) as total') 
     .group('tasks.user_id, jobs.id') 
     .order('tasks.user_id') 

uzyskać to, co jest blisko tego, co chcę

- !ruby/object:Job 
    attributes: 
    user_id: '1' 
    total: '60.00' 
- !ruby/object:Job 
    attributes: 
    user_id: '1' 
    total: '50.00' 
- !ruby/object:Job 
    attributes: 
    user_id: '2' 
    total: '120.00' 
- !ruby/object:Job 
    attributes: 
    user_id: '2' 
    total: '100.00' 

Jak mogę pogrupować to przez user_id i zsumować sumę tak, że mam coś takiego?

user_id: 1 
total: 110 
user_id: 2 
total: 220 
+0

mógłbyś wyjaśnić relacje między swoimi modelami. w jaki sposób 'task' i' jobs' są połączone? – gabrielhilal

+1

wydaje się, że lepiej pasuje do surowego SQL lub Arel niż do ActiveRecord. –

+0

Nie myślałeś o widokach SQL? –

Odpowiedz

1

thansk za odpowiedzi.

udało mi się rozwiązać ten problem z

user_totals = jobs.to_a.group_by(&:user_id).map{ |user_id,jobs| {:user_id => user_id.to_i, :total => jobs.sum {|j| j.total.to_f} }} 
=> [{:user_id=>1, :total=>110.0}, {:user_id=>2, :total=>220.0}] 
0

Może wystarczy prosta każda pętla, tworząc skrót?

user_totals = Hash.new(0) 
jobs.each do |job| 
    user_totals[job.user_id] += job.total 
end 

To daje:

user_totals = {"1":110, "2":220} 
0

użycie group_by

Hash[jobs.group_by(&:user_id).map {|user_id, jobs| [user_id, jobs.reduce{ |m, job| m+job.total] }] 

Coś podobnego (nie testowałem go, więc może nie działać jak to jest)

Powiązane problemy