creating a model registry

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:

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

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

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

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

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.

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

Very interesting... thanks for the follow up.