Method gives ActiveRecord::Relation error?

一个人想着一个人 提交于 2019-12-20 07:48:38

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!