Model Registry

Sometimes I have a module that needs to find all models that mix it in. I was trying to find all the models, and then select ones that had a given property set. Not only is this inefficient, it's bug prone too. A better way is to create a registry with the module:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
module Wacko
  @@wackos = []
  mattr_reader :wackos
  def self.included(base)
    @@wackos.push(base)
    base.extend ClassMethods
  end

  def ClassMethods
    def happy?
      true
    end
  end
end

Then you can do this to make sure all wackos are happy:


Wacko.wackos.all?(&:happy?)

Yay, except that models mixing in Wacko won't be evaluated until they're called for, which could be never. So you need to load your models at boot. If you try to do it with require, you'll run into problems in development mode that have to do with cache_classes, and are best explained by reading dependecies.rb. Instead, use dependecies.rb's very own "require_or_load" which seems to play nicely with all environments. In config/environment.rb:


Dir.glob(File.join(File.join(RAILS_ROOT, 'app', 'models'), '**', '*.rb')).each{|m|require_or_load m}

Leave a Reply