Rails model class method for collection of objects

喜欢而已 提交于 2019-12-10 01:45:36

问题


I'm having trouble writing class methods to use on collections of ActiveRecord objects. I've run into this issue twice in the last couple of hours, and it seems like a simple problem, so I know I'm missing something, but I haven't been able to find answers elsewhere.

Example:

class Order < ActiveRecord::Base

  belongs_to :customer

  scope :month, -> { where('order_date > ?', DateTime.now.beginning_of_month.utc) }

  def self.first_order_count
    map(&:first_for_customer?).count(true)
  end

  def first_for_customer?
    self == customer.orders.first
    # this self == bit seems awkward, but that's a separate question...
  end

end

If I call Order.month.first_order_count, I get NoMethodError: undefined method 'map' for #<Class:...

As far as I know, that's because map can't be called directly on Order, but needs an Enumerable object instead. If I call Order.year.map(&:first_for_customer?).count(true), I get the desired result.

What's the right way to write methods to use on a collection of ActiveRecord objects, but not on the class directly?


回答1:


In your case, you can use a trick in this case.

def self.first_order_count
   all.map(&:first_for_customer?).count(true)
end

Will do the trick, without any other problems, this way if you concatenate this method on where clause you still get results from that where, this way you get what you need if you call this method directly on Order.




回答2:


ActiveRecord collections are usually manipulated using scopes, with the benefits of being able to chain them and let the database do the heavy lifting. If you must manage it in Ruby, you can start with all.

def self.first_order_count
  all.map(&:first_for_customer?).count(true)
end

What are you trying to achieve with your code though?



来源:https://stackoverflow.com/questions/31155085/rails-model-class-method-for-collection-of-objects

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