# How to apply a class method to a limited collection of the objects?

**URL:** <https://www.ruby-forum.com/t/how-to-apply-a-class-method-to-a-limited-collection-of-the-objects/146459>\
**Category:** Rails\
**Created:** [August 21, 2008, 11:29am UTC](https://www.ruby-forum.com/t/how-to-apply-a-class-method-to-a-limited-collection-of-the-objects/146459 "2008-08-21T11:29:30Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![deegee](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/e19adc/32.png) [@deegee](https://www.ruby-forum.com/u/deegee)\
**Post date:** [August 21, 2008, 11:29am UTC](https://www.ruby-forum.com/t/how-to-apply-a-class-method-to-a-limited-collection-of-the-objects/146459/1 "2008-08-21T11:29:30Z")

</div>

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?

Dirk.

---

<div class="post-metadata">

**Author:** ![deegee](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/e19adc/32.png) [@deegee](https://www.ruby-forum.com/u/deegee)\
**Post date:** [August 21, 2008, 12:05pm UTC](https://www.ruby-forum.com/t/how-to-apply-a-class-method-to-a-limited-collection-of-the-objects/146459/2 "2008-08-21T12:05:17Z")

</div>

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.

am i close? i might be mumblinng crap.

let me know

---

<div class="post-metadata">

**Author:** ![deegee](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/e19adc/32.png) [@deegee](https://www.ruby-forum.com/u/deegee)\
**Post date:** [August 21, 2008, 4:57pm UTC](https://www.ruby-forum.com/t/how-to-apply-a-class-method-to-a-limited-collection-of-the-objects/146459/3 "2008-08-21T16:57:39Z")

</div>

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.

Dirk.

---

<div class="post-metadata">

**Author:** ![deegee](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/e19adc/32.png) [@deegee](https://www.ruby-forum.com/u/deegee)\
**Post date:** [August 21, 2008, 5:44pm UTC](https://www.ruby-forum.com/t/how-to-apply-a-class-method-to-a-limited-collection-of-the-objects/146459/4 "2008-08-21T17:44:00Z")

</div>

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…

---

<div class="post-metadata">

**Author:** ![deegee](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/e19adc/32.png) [@deegee](https://www.ruby-forum.com/u/deegee)\
**Post date:** [August 21, 2008, 6:49pm UTC](https://www.ruby-forum.com/t/how-to-apply-a-class-method-to-a-limited-collection-of-the-objects/146459/5 "2008-08-21T18:49:03Z")

</div>

Please let me know how it works out.

---

<div class="post-metadata">

**Author:** ![deegee](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/e19adc/32.png) [@deegee](https://www.ruby-forum.com/u/deegee)\
**Post date:** [August 22, 2008, 10:20am UTC](https://www.ruby-forum.com/t/how-to-apply-a-class-method-to-a-limited-collection-of-the-objects/146459/6 "2008-08-22T10:20:33Z")

</div>

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!
