# Has\_many and class function

**URL:** <https://www.ruby-forum.com/t/has-many-and-class-function/111074>\
**Category:** Rails\
**Created:** [August 2, 2007, 11:47am UTC](https://www.ruby-forum.com/t/has-many-and-class-function/111074 "2007-08-02T11:47:33Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Fabien\_J](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/51bf81/32.png) [@Fabien\_J](https://www.ruby-forum.com/u/Fabien_J)\
**Post date:** [August 2, 2007, 11:47am UTC](https://www.ruby-forum.com/t/has-many-and-class-function/111074/1 "2007-08-02T11:47:33Z")

</div>

Hello,

i have two models :

class Container \< ActiveRecord::Base  
has\_many :bottles  
end

class Bottle \< ActiveRecord::Base  
belongs\_to :container

def self.find\_all\_from\_container(container)  
container.bottles.find(:all)  
end  
end

i was asking myself if there was a better way to write the function  
find\_all\_from\_container : i can call it from an instance of Container  
but how to pass the container instance directly (ie without giving  
the argument). To replace this :

@container = Container.find(id)  
@bottles = Bottle.find\_all\_from\_container(@container)

by something like this :

@container . Container.find(id)  
@bottles = @container.bottles.find\_all\_from\_container

---

<div class="post-metadata">

**Author:** ![Fabien\_J](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/51bf81/32.png) [@Fabien\_J](https://www.ruby-forum.com/u/Fabien_J)\
**Post date:** [August 2, 2007, 12:02pm UTC](https://www.ruby-forum.com/t/has-many-and-class-function/111074/2 "2007-08-02T12:02:36Z")

</div>

Hi,

2007/8/2, Fabien J. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> end  
> …  
> To replace this :
> 
> @container = Container.find(id)  
> @bottles = Bottle.find\_all\_from\_container(@container)
> 
> by something like this :
> 
> @container . Container.find(id)  
> @bottles = @container.bottles.find\_all\_from\_container

has\_many gives you what you want for free.

@container.bottles

results in all bottles in the container. No need to call find.

Lutz

---

<div class="post-metadata">

**Author:** ![Fabien\_J](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/51bf81/32.png) [@Fabien\_J](https://www.ruby-forum.com/u/Fabien_J)\
**Post date:** [August 2, 2007, 12:10pm UTC](https://www.ruby-forum.com/t/has-many-and-class-function/111074/3 "2007-08-02T12:10:38Z")

</div>

On Aug 2, 2007, at 12:02 PM, Lutz H. wrote:

> > by something like this :
> > 
> > @container . Container.find(id)  
> > @bottles = @container.bottles.find\_all\_from\_container
> 
> has\_many gives you what you want for free.
> 
> @container.bottles
> 
> results in all bottles in the container. No need to call find.

I should have add more code in find\_all\_from\_container function. The  
idea is not to get every entries but to scope entries and perform  
some actions on them, like :

def self.fill\_empty(container)  
bottles = container.bottles.find(:all, :conditions =\> {:is\_empty  
=\> true})  
bottles.each {|bottle| bottle.fill}  
end

---

<div class="post-metadata">

**Author:** ![Fabien\_J](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/51bf81/32.png) [@Fabien\_J](https://www.ruby-forum.com/u/Fabien_J)\
**Post date:** [August 2, 2007, 12:20pm UTC](https://www.ruby-forum.com/t/has-many-and-class-function/111074/4 "2007-08-02T12:20:39Z")

</div>

On Aug 2, 2007, at 12:13 PM, Lutz H. wrote:

> > =\> true})  
> > bottles.each {|bottle| bottle.fill}  
> > end
> 
> You can do this by using select:
> 
> container.bottles.select { |bottle| bottle.is\_empty }
> 
> The block given to select must return true for every object to be  
> included in the resulting list.

Thanks for this help, but i just want to get the container instance  
in class function to perform various things, regardless of any code  
in it.

---

<div class="post-metadata">

**Author:** ![Fabien\_J](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/51bf81/32.png) [@Fabien\_J](https://www.ruby-forum.com/u/Fabien_J)\
**Post date:** [August 2, 2007, 12:13pm UTC](https://www.ruby-forum.com/t/has-many-and-class-function/111074/5 "2007-08-02T12:13:38Z")

</div>

Hi,

2007/8/2, Fabien J. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> I should have add more code in find\_all\_from\_container function. The  
> idea is not to get every entries but to scope entries and perform  
> some actions on them, like :
> 
> def self.fill\_empty(container)  
> bottles = container.bottles.find(:all, :conditions =\> {:is\_empty  
> =\> true})  
> bottles.each {|bottle| bottle.fill}  
> end

You can do this by using select:

container.bottles.select { |bottle| bottle.is\_empty }

The block given to select must return true for every object to be  
included in the resulting list.

Lutz

---

<div class="post-metadata">

**Author:** ![Fabien\_J](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/51bf81/32.png) [@Fabien\_J](https://www.ruby-forum.com/u/Fabien_J)\
**Post date:** [August 2, 2007, 12:29pm UTC](https://www.ruby-forum.com/t/has-many-and-class-function/111074/6 "2007-08-02T12:29:40Z")

</div>

On Aug 2, 2007, at 12:22 PM, Pratik wrote:

> It really helps if you can ask your question with exact code you’re  
> using.

actually, there is no code about this, i just want to know if it is  
possible to get the instance without explicitly giving it in the call.

This is more by curiosity rather than a strict code question.

---

<div class="post-metadata">

**Author:** ![Fabien\_J](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/51bf81/32.png) [@Fabien\_J](https://www.ruby-forum.com/u/Fabien_J)\
**Post date:** [August 2, 2007, 12:23pm UTC](https://www.ruby-forum.com/t/has-many-and-class-function/111074/7 "2007-08-02T12:23:39Z")

</div>

It really helps if you can ask your question with exact code you’re  
using.

On 8/2/07, Fabien J. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > > @container = Container.find(id)
> 
> end
> 
> >

–  
Cheers!

- Pratik  
[http://m.onkey.org](http://m.onkey.org)

---

<div class="post-metadata">

**Author:** ![Fabien\_J](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/51bf81/32.png) [@Fabien\_J](https://www.ruby-forum.com/u/Fabien_J)\
**Post date:** [August 2, 2007, 2:21pm UTC](https://www.ruby-forum.com/t/has-many-and-class-function/111074/8 "2007-08-02T14:21:56Z")

</div>

Hi –

On Thu, 2 Aug 2007, Fabien J. wrote:

> This is more by curiosity rather than a strict code question.

The thing is, the instance is the class object when you call a class  
method:

class C  
end

def C.greet  
puts “Hi from #{self}”  
end

C.greet # Hi from C

There’s no instance of C involved; you’re sending the message directly  
to C. A class is (by design) an entirely different object from its  
instances (except for constants, which an instance method can refer  
to from “below”, and except for class variables, which are weird and  
quasi-global).

It’s possible to engineer things so that a class method can have  
access of a sort to an instance via a block. Here’s an example (and  
if you look at the source code for AR associations, which let you do  
things like this, you’ll see some much more highly-evolved examples):

class A  
def self.c\_method(&block)  
include Module.new { define\_method(“m”, &block) }  
end  
end

class B \< A  
c\_method { puts “Hi; I’m #{self}.” }  
end

B.new.m # Hi; I’m #\<B:0x1ea08c\>.

It’s not exactly what you want, but it might give you some ideas.

David

–

- Books:  
RAILS ROUTING (new! [http://www.awprofessional.com/title/0321509242](http://www.awprofessional.com/title/0321509242))  
RUBY FOR RAILS ([Ruby for Rails](http://www.manning.com/black))
- Ruby/Rails training  
& consulting: Ruby Power and Light, LLC ([http://www.rubypal.com](http://www.rubypal.com))
