问题
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?
回答1:
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.
回答2:
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
来源:https://stackoverflow.com/questions/11942377/method-gives-activerecordrelation-error