# Creating a model registry

**URL:** <https://www.ruby-forum.com/t/creating-a-model-registry/131306>\
**Category:** Rails\
**Created:** [March 7, 2008, 8:50pm UTC](https://www.ruby-forum.com/t/creating-a-model-registry/131306 "2008-03-07T20:50:26Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![ISESSmith-Heister](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/ea666f/32.png) [@ISESSmith-Heister](https://www.ruby-forum.com/u/ISESSmith-Heister)\
**Post date:** [March 7, 2008, 8:50pm UTC](https://www.ruby-forum.com/t/creating-a-model-registry/131306/1 "2008-03-07T20:50:26Z")

</div>

Hi all,

This is a problem I’ve approached so many times and always worked  
around, that now I want to solve it once and for all. Say I have  
something like this:

* * *

class X \< ActiveRecord::Base  
acts\_as\_wacky  
end

module Wackinator  
class ControlAllWackos  
@@wackos = []  
def self.kill\_wackos  
@@wackos.each(&:kill)  
end  
end

## def acts\_as\_wacky ControlAllWackos.wackos \<\< self # do stuff end end

I know that code won’t actually run, but hopefully it serves to  
illustrate my point.

Which is that since Rails loads models with load\_missing\_constant, you  
can’t count on X having been defined, and therefore you can’t count on  
ControlAllWackos.wackos being accurate.

Ok, so there’s a couple possible solutions:

- load all your models right away with Dir.glob(File.join(RAILS\_ROOT,  
‘app’, ‘models’, ‘\*.rb’)).each{|f|require f}

this is problematic with cache\_classes in development mode, because  
cache\_classes does some voodoo around unloading classes, and you end  
up with lots of errors.

- statically define @@wackos:

module Wackinator  
class ControlAllWackos  
@@wackos = %w(X Y Z)  
def self.kill\_wackos  
@@wackos.map(&:classify).each(&:kill)  
end  
end

def acts\_as\_wacky  
# do stuff  
end  
end

which is difficult to maintain, and ugly too.

This is kind of a chicken-and-egg problem, and I don’t anticipate  
finding a better solution than the static definition. But I thought  
some of ye ruby wizzards might know some arcana that might be of use  
here.

Thanks!  
-Ian

---

<div class="post-metadata">

**Author:** ![ISESSmith-Heister](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/ea666f/32.png) [@ISESSmith-Heister](https://www.ruby-forum.com/u/ISESSmith-Heister)\
**Post date:** [March 8, 2008, 1:16am UTC](https://www.ruby-forum.com/t/creating-a-model-registry/131306/2 "2008-03-08T01:16:48Z")

</div>

I. E. Smith-Heisters wrote:

> * * *
> 
> class X \< ActiveRecord::Base  
> acts\_as\_wacky  
> end
> 
> module Wackinator  
> class ControlAllWackos  
> @@wackos = []  
> def self.kill\_wackos  
> @@wackos.each(&:kill)  
> end  
> end
> 
> ## def acts\_as\_wacky ControlAllWackos.wackos \<\< self # do stuff end end

require ‘wackinator’  
class X \< ActiveRecord::Base

hth

ilan

---

<div class="post-metadata">

**Author:** ![ISESSmith-Heister](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/ea666f/32.png) [@ISESSmith-Heister](https://www.ruby-forum.com/u/ISESSmith-Heister)\
**Post date:** [March 8, 2008, 1:20am UTC](https://www.ruby-forum.com/t/creating-a-model-registry/131306/3 "2008-03-08T01:20:58Z")

</div>

On 3/7/08, Ilan B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > ## class ControlAllWackos end
> 
> require ‘wackinator’  
> class X \< ActiveRecord::Base
> 
> hth
> 
> ilan

But that code won’t be evaluated until the model X is used somewhere,  
which is totally indeterminate. So if you boot your app and right away  
call Wackinator::ControlAllWackos.kill\_wackos, chances are X _hasn’t_  
been loaded and @@wackos will be empty. Or am I missing something?

Thanks,  
Ian

---

<div class="post-metadata">

**Author:** ![ISESSmith-Heister](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/ea666f/32.png) [@ISESSmith-Heister](https://www.ruby-forum.com/u/ISESSmith-Heister)\
**Post date:** [March 9, 2008, 12:23am UTC](https://www.ruby-forum.com/t/creating-a-model-registry/131306/4 "2008-03-09T00:23:44Z")

</div>

Hm, yes… but then you can’t test your code. Given that choice, I’d  
rather have a hard-to-maintain static list. Perhaps if I look further  
into _why_ things don’t work in development I can find a way of fixing  
it. But that still wouldn’t address the possibility of there being a  
model defined somewhere else than app/models, which I guess is a  
sufficiently rare case to ignore.

---

<div class="post-metadata">

**Author:** ![ISESSmith-Heister](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/ea666f/32.png) [@ISESSmith-Heister](https://www.ruby-forum.com/u/ISESSmith-Heister)\
**Post date:** [March 8, 2008, 9:03pm UTC](https://www.ruby-forum.com/t/creating-a-model-registry/131306/5 "2008-03-08T21:03:54Z")

</div>

What about using the Dir.glob trick only through initializers for  
production.rb?

---

<div class="post-metadata">

**Author:** ![ISESSmith-Heister](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/ea666f/32.png) [@ISESSmith-Heister](https://www.ruby-forum.com/u/ISESSmith-Heister)\
**Post date:** [March 10, 2008, 8:16pm UTC](https://www.ruby-forum.com/t/creating-a-model-registry/131306/6 "2008-03-10T20:16:22Z")

</div>

Very interesting… thanks for the follow up.

---

<div class="post-metadata">

**Author:** ![ISESSmith-Heister](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/ea666f/32.png) [@ISESSmith-Heister](https://www.ruby-forum.com/u/ISESSmith-Heister)\
**Post date:** [March 10, 2008, 7:00pm UTC](https://www.ruby-forum.com/t/creating-a-model-registry/131306/7 "2008-03-10T19:00:57Z")

</div>

Ok, looking into cache\_classes led me to this solution, which seems to  
work:

in config/environment.rb:

silence\_warnings do  
Dir.glob(File.join(RAILS\_ROOT, ‘app’, ‘models’,  
‘\*.rb’)).each{|m|require\_or\_load m}  
end

elsewhere:

module Wackinator  
class ControlAllWackos  
@@wackos = []  
def self.kill\_wackos  
@@wackos.each(&:kill)  
end  
end

def acts\_as\_wacky  
ControlAllWackos.wackos \<\< self

# do stuff

end  
end

The important part is that you have to use require\_or\_load instead of  
require so that eagerly loading all the models works in development  
mode. From there you can do whatever you want, in my case I’m  
registering all my wackos so that they’re available in  
ControlAllWackos.wackos.

Work for me at the moment…

-Ian
