Reputation: 27232
I have 3 models called Price, UnitPrice and Purchase. The Price and UnitPrice models have an attribute called amount
that I'm trying to scope to and get the total sum of both combined. I created two scopes, one for the total sum of both models. The other scope is to get the date
attribute of both model's date
fields.
I'm trying to do this:
<%= number_to_currency(current_user.purchases.today.total)
But get the error:
NoMethodError in pages#home
undefined method `today' for #<ActiveRecord::Relation:0x77f94c0>
My Code:
class Purchase < ActiveRecord::Base
belongs_to :user
belongs_to :price
belongs_to :unit_price
def total
self.price.sum(:amount) + self.unit_price.sum(:amount)
end
def today
self.price.where(:date => Date.today) && self.unit_price.where(:date=> Date.today)
end
end
class Price < ActiveRecord::Base
attr_accessible :amount, :date
belongs_to :user
has_many :purchases
end
class UnitPrice < ActiveRecord::Base
attr_accessible :amount, :date
belongs_to :user
has_many :purchases
end
What should I do?
Upvotes: 0
Views: 1546
Reputation: 1750
The methods total
and today
are defined on a model object. When you call current_user.purchases
you associate to a relation which is has_many
which means that in the end it's the Array. Therefore you can't call Purchase methods on it. You can do it this way:
class Purchase < ActiveRecord::Base
# ...
scope :today, lambda { joins(:unit_price, :price).
where(:price => {:date => Date.today},
:unit_price => { :date => Date.today }) }
def total
self.price.sum(:amount) + self.unit_price.sum(:amount)
end
end
And then call it like this:
<%= number_to_currency(current_user.purchases.today.inject{ |sum, p| sum + p.total }) %>
Scope can be called on a relation.
You need to call inject since again total
is Purchase method and the relation is Array so you need to aggregate the array. In order to keep the code clean you may want to define a today_purchases_total
method on User
so then you can call it like:
<%= number_to_currency(current_user.today_purchases_total) %>
For more info about this you may refer to http://guides.rubyonrails.org/active_record_querying.html#scopes and all RoR guides in general.
Upvotes: 1
Reputation: 51717
I think your problem may be that you're using class methods instead of instance methods. In your Purchase class, remove the self.
before the method definitions:
class Purchase < ActiveRecord::Base
def total
self.price.sum(:amount) + self.unit_price.sum(:amount)
end
def today
self.price.where(:date => Date.today) && self.unit_price.where(:date=> Date.today)
end
end
Upvotes: 2