how to apply a class method to a limited collection of the objects?

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

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 - # or however you compute it

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.

am i close? i might be mumblinng crap.

let me know

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’)


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

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...

Please let me know how it works out.

Yes, tried it out and it works perfectly. I looks like all the options
you can use for associations can also be used on scopes, which is
really cool!