Reputation: 27202
In my Rails 3.2.8 application, I'm trying to calculate all of the users products and tax amount in total. It should get the total of the Products and then the Tax on each product.
class Product
attr_accessible :amount, :location_id, :tax_id
belongs_to :tax
belongs_to :location
belongs_to :user
belongs_to :tax, :class_name => "Tax"
def self.total
self.sum(:amount) + self.tax.sum(:amount)
end
end
Tax.rb
class Tax < ActiveRecord::Base
attr_accessible :amount, :date, :location_id
belongs_to :user
belongs_to :location
has_many :products
end
So when I try a scope like this:
<%= number_to_currency(current_user.products.total) %>
This of course gives me an error:
undefined method `tax' for #<Class:0x57f5298>
How can I write this to make it work?
Thank you.
Upvotes: 0
Views: 326
Reputation: 21791
From this line
<%= number_to_currency(current_user.products.total) %>
I understood that for current user you need the sum from his products and taxes. What you have done before is not related to the current user but to the whole table of products instead, and of course some product in this table can be not related to the current user.
So here's what I think how it might be.
#Instance method for current user
class User < ...
def product_tax_total
products.joins(:tax).select('SUM(products.amount + taxes.amount) AS sum').sum
end
end
And use it like this:
<%= number_to_currency(current_user.product_tax_total) %>
Update:
You can use scope to chain the queries:
class Product
scope :today, lambda { where(:date => Date.today) }
end
And then chain it
class User < ...
def product_tax_total
products.today.joins(:tax).select('SUM(products.amount + taxes.amount) AS sum').sum
end
end
Upvotes: 1
Reputation: 4010
I'm not great with ActiveRecord's newer query methods. I guest I'm a little old fashioned and have a tendency to lean more towards SQL, but this should "efficiently" get what you want.
def self.total
self.select('sum(products.amount + taxes.amount) AS sum').joins(:tax).try(:sum, 0)
end
Upvotes: 1
Reputation: 1835
tax
is a Product's instance method, not of class Product
try the following (weak performance):
class Product
belongs_to :tax
def self.total
self.sum(:amount) + all.map(&:tax).map(&:amount).sum
end
end
Upvotes: 3