# Noob: where to put the find(:all) to use with collection\_select() in multiple places?

**URL:** <https://www.ruby-forum.com/t/noob-where-to-put-the-find-all-to-use-with-collection-select-in-multiple-places/129814>\
**Category:** Rails\
**Created:** [February 21, 2008, 7:39pm UTC](https://www.ruby-forum.com/t/noob-where-to-put-the-find-all-to-use-with-collection-select-in-multiple-places/129814 "2008-02-21T19:39:17Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![rpardee](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/e47c2d/32.png) [@rpardee](https://www.ruby-forum.com/u/rpardee)\
**Post date:** [February 21, 2008, 7:39pm UTC](https://www.ruby-forum.com/t/noob-where-to-put-the-find-all-to-use-with-collection-select-in-multiple-places/129814/1 "2008-02-21T19:39:17Z")

</div>

Hey All,

I’m just starting out w/rails & have a toy app w/just 2 types of  
things right now: People and Organizations. Person :belongs\_to  
organization and Organization :has\_many people.

I’d like to provide a select control showing the available  
organizations on the people/new and people/edit actions (or whatever  
they’re called) and so I’m using collection\_select to do that. My  
question is where to put the call to Organization.find(:all) to grab  
out the data I need to populate the select control. It seems like I  
should be able to do that just once & stash the results in a class var  
for use anyplace in the people controller class.

But when I go to put that list in a class variable in my (scaffold-  
generated) people\_controller.rb file like so:

class PeopleController \< ApplicationController

```
@@organizations = Organization.find(:all)

def new
  # blah blah blah
end

# etc...

```

end

And then try to access this from views/people/new.html.erb w/this  
line:

```
<%= collection_select(:person, :organization_id,

```

@@organizations, :id, :name) %\>

I get a NameError on that call to collection\_select() w/msg  
“uninitialized class variable @@organizations in  
ActionView::Base::CompiledTemplates”

So… where can I stash the results of that .find(:all) call so that  
the same data is available for both actions?

Thanks!

-Roy

---

<div class="post-metadata">

**Author:** ![rpardee](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/e47c2d/32.png) [@rpardee](https://www.ruby-forum.com/u/rpardee)\
**Post date:** [February 21, 2008, 9:50pm UTC](https://www.ruby-forum.com/t/noob-where-to-put-the-find-all-to-use-with-collection-select-in-multiple-places/129814/2 "2008-02-21T21:50:11Z")

</div>

2008/2/21, Roy P. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

Hi,

> ```
> <%= collection_select(:person, :organization_id,
> 
> ```
> 
> @@organizations, :id, :name) %\>

Even if this would work, I’d strongly advise against  
it since the view has more knowledge of your controller  
than it needs to and turns your nice MVC app into  
a tangled mess. Just use a normal instance variable  
here (@organizations). That gives the controller a chance  
to manipulate the organizations list (e.g. certain users  
may only create people for a subset of all available  
organizations, etc.) without requiring changes in the view.

Regarding the controller: Isn’t it possible that the  
list of organizations changes? Your current code doesn’t  
account for that. In this case the right way is a simple

```
def new
  @organizations = Organization.find(:all)
  ...

def edit
  @organizations = Organization.find(:all)
  ...

```

If the organizations don’t change, and you _really_  
want to load the only once, just add

```
def new
  @organizations = @@organizations
  ...

```

HTH,  
Stefan

---

<div class="post-metadata">

**Author:** ![rpardee](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/e47c2d/32.png) [@rpardee](https://www.ruby-forum.com/u/rpardee)\
**Post date:** [February 21, 2008, 11:07pm UTC](https://www.ruby-forum.com/t/noob-where-to-put-the-find-all-to-use-with-collection-select-in-multiple-places/129814/3 "2008-02-21T23:07:33Z")

</div>

Thanks for the response Stefan!

You’re absolutely right that organizations can change–in the fullness  
of time I’m going to want to stash that list in whatever rails has for  
an application-wide cache, and refresh it whenever the list changes.  
(I think there are activerecord hook methods I can use for that,  
aren’t there?).

But for now I’m just trying to get oriented to rails. It seems  
strange to me that instance vars are available in the view, but class  
vars aren’t, and putting multiple calls to .find(:all) seems overly  
chatty w/the database, and not as DRY as could be.

Maybe what I need to do is just read up on caching in rails & see what  
I can see on that…

Thanks!

-Roy

On Feb 21, 12:49 pm, “Stefan L.” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![rpardee](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/e47c2d/32.png) [@rpardee](https://www.ruby-forum.com/u/rpardee)\
**Post date:** [February 22, 2008, 12:08pm UTC](https://www.ruby-forum.com/t/noob-where-to-put-the-find-all-to-use-with-collection-select-in-multiple-places/129814/4 "2008-02-22T12:08:03Z")

</div>

Roy P. wrote:

> But for now I’m just trying to get oriented to rails. It seems  
> strange to me that instance vars are available in the view, but class  
> vars aren’t, and putting multiple calls to .find(:all) seems overly  
> chatty w/the database, and not as DRY as could be.
> 
> Maybe what I need to do is just read up on caching in rails & see what  
> I can see on that…

It’s not that this isn’t DRY, it’s that each call to the method must  
allow for the fact that the Organization model changes. The controller  
shouldn’t assume that it is the only way of accessing a model which is  
what you’ll do by updating a controller class variable whenever the  
controller changes a model. This will lead to problems down the line if  
you end up with other accesses to the model. This may not seem  
important for this application, but it would be a bad habit to get into  
as it will definitely bite you on a larger project.

It is unlikely you are expecting a large number of organisations as that  
would make your select list unwieldy. So obtaining the list from the  
database should be fairly low cost. Let your database handle data  
caching and let your application handle access control and logic. When  
doing a find(:all) the database will do a bulk load in one call which  
shouldn’t be much more expensive than getting a single row for small  
amounts of data (and so comparable to the cost of adding the new People  
record) and if you are using a decent database, it may have cached the  
results for you anyway. Also, at this stage, you don’t know how  
noticable caching this value yourself will be. Use profiling to decide  
where to target performance efforts.

When starting out, it’s probably more useful to concentrate on  
functionality rather than minor details and look at how you can refactor  
later once the application takes shape. As you play with more  
applications and look at other’s code, you’ll start recognising  
opportunities for factoring earlier in development.

Finally, if you really want to cache the records, put them where they  
belong. In the model. All access must go through the model, so use the  
model’s after\_\* hooks to keep a cache in the model and provide access to  
this cache (which will even be available from a view if you really need  
it there).

---

<div class="post-metadata">

**Author:** ![rpardee](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/e47c2d/32.png) [@rpardee](https://www.ruby-forum.com/u/rpardee)\
**Post date:** [February 22, 2008, 6:24pm UTC](https://www.ruby-forum.com/t/noob-where-to-put-the-find-all-to-use-with-collection-select-in-multiple-places/129814/5 "2008-02-22T18:24:31Z")

</div>

Ah, that makes perfect sense–thanks much for the response. I  
definitely take the point that it’s too early at this point to fuss  
over performance. Like I say, I’m still getting oriented–and not  
just to rails I guess, but to MVC in general.

I got together w/some friends last night & they helped me to write  
this bit here, which seems to work (even as the list of orgs changes)  
_and_ satisfies my db-chattiness concern, I think, w/out breaking the  
MVC separation of concerns.

class Organization \< ActiveRecord::Base  
has\_many :people  
def self.get\_list  
@@all\_organizations ||= self.find(:all, :select =\> ‘id, name’)  
end  
def before\_save  
@@all\_organizations = nil  
end  
end

That gives me an Organization.get\_list method that I can call from my  
Person views (and any view? I guess probably…).

Thanks!

-Roy

On Feb 22, 3:08 am, Mark B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![rpardee](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/e47c2d/32.png) [@rpardee](https://www.ruby-forum.com/u/rpardee)\
**Post date:** [February 22, 2008, 7:33pm UTC](https://www.ruby-forum.com/t/noob-where-to-put-the-find-all-to-use-with-collection-select-in-multiple-places/129814/6 "2008-02-22T19:33:00Z")

</div>

Doesn’t Rails 2.0 already do SQL caching?
