问题
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