Hi,
I just can't figure out how to do it, i'm sure it's pretty simple: I
have a model Order with a few named_scope methods
(:completed, :incompleted, :recent). Now I'd like to define a method
that returns the latest date an order was placed. The method shouldn't
just do this over the entire collection of orders, but also over any
of the scopes. I know how to define a method within a specific scope
(named_scope :recent do def latest_date <...> end end), but surely
there's a way I don't need to define it 3 times to be able to access
it within each scope?
If I define the class method Order#latest_date, how can I call it on a
subset of orders, either found by a named_scope or any other
find(:conditions => ...) method?
I think you are mixing up class and instance methods, maybe im wrong
but:
If every order in the system has a latest_date, or every order has a
way of finding it out, your method should be a instance method. so
class Order < AR::Base
named_scope :recent
named_scope :whatever
def latest_date
self.order_date - Time.now # or however you compute it
end
end
when you get an order may it be via a find or a named scope (which is
just a find with some constraints), you can always call the method on
the instance.
A class method would work if all orders had the same latest_date,
which i cant figure out why would that be.
Ok, I think I didn’t make myself clear on that one. No I know the difference between class and instance methods. My Orders have a date attribute. I’m looking to find the most recent order based on that date attribute. If I want to do that on all Orders, I can just define a class method:
class Order < AR::Base
named_scope :whatever, :conditions => …
def self.latest_date
latest_order = first(:order => ‘date DESC’)
latest_order.date
end
end
I can then do Order.latest_date to get the date of the most recent order.
But I can’t do Order.whatever.latest_date to find the latest order within the group of ‘whatever’ orders. That’s what I’m trying to do. Of course, in the simple case above, I could just do
Order.whatever.first(:order => ‘date DESC’).date
and because it’s quite a simple query, that’s okay, but for more complex calculations based on a collection of objects, that would not be very DRY.
Can’t use instance method here because a specific Order object doesn’t have the knowlegde about latest_date.
Maybe I found an answer to my own question. I already knew I could
define an extension on a named_scope:
named_scope :whatever, :conditions => ... do
def latest_date
first(:order => 'date DESC').date
end
end
As I stated in my first post, I need to define the same extension for
all my scopes.
It looks like I can use the :extend options, like on associations, to
put my extension in a Module and re-use in all my scopes:
named_scope :whatever, :conditions => ..., :extend => FindLatestDate
Module FindLatestDate
def latest_date
first(:order => 'date DESC').date
end
end
I'll try this and let you know if it works. Actually, the book AWDWR
has so much information, it's just a matter of reading 3-4 times to
grasp the gritty details...