Constant caching, modules and STI

Hi there,
I’ve been following one of the recipes in the Advanced Rails Recipes
books, and have arrived for my own particular needs at this scenario:

I want to cache some options data in constants at loadtime (as per the
recipe) for dropdown menus in a form
All of the different options are in a single table and use STI.

I have the following module in my initializer folder, with
caches_constant called on the main activerecord data class (RnData):

#######
module ConstantCache
module ClassMethods
def caches_constants
const_set(self.name.to_s.underscore.upcase, [‘my’, ‘array’,
‘here’])
end
end
end

ActiveRecord::Base.send(:extend, ConstantCache::ClassMethods)
########

What happens thus far is that all of the subclasses have a constant
defined with the name of the parent class.

e.g.
RnData::RN_DATA
=> ‘12345’
RnAuto::RN_DATA
=>‘12345’
RnAuto::RN_AUTO

LoadError: Expected /Users/dorian/Sites/mysite/app/models/rn/
rn_auto.rb to define RN_AUTO
from /opt/local/lib/ruby/gems/1.8/gems/activesupport-2.2.2/lib/
active_support/dependencies.rb:428:in load_missing_constant' from /opt/local/lib/ruby/gems/1.8/gems/activesupport-2.2.2/lib/ active_support/dependencies.rb:77:inconst_missing_not_from_s3_library’
from /opt/local/lib/ruby/gems/1.8/gems/aws-s3-0.5.1/lib/aws/s3/
extensions.rb:174:in const_missing' from /opt/local/lib/ruby/gems/1.8/gems/activesupport-2.2.2/lib/ active_support/dependencies.rb:89:inconst_missing’
from /opt/local/lib/ruby/gems/1.8/gems/activesupport-2.2.2/lib/
active_support/dependencies.rb:439:in load_missing_constant' from /opt/local/lib/ruby/gems/1.8/gems/activesupport-2.2.2/lib/ active_support/dependencies.rb:93:inconst_missing’
from (irb):2

Ideally I would like something along the lines of:

RnData::RN_DATA
RnData::RN_AUTO
RnData::RN_INCOME
or just
RnAuto::OPTIONS
RnIncome::OPTIONS

as long as it has the right info for the subclass in it, and not just
the parent inherited across all subclass.

So, I’m wondering if there’s a way to write this so that it will run
caches_constant for subclass, or do I have to include the
caches_constants line in all my subclasses?

I’ve replacing caches_constants with this which seems to work, but I’m
worried I may be overwriting something critical in activerecord:

class RnData < ActiveRecord::Base
def self.inherited(subclass)
subclass.caches_constants
end
end

any help much appreciated!
thanks
dorian

On 23 Feb 2009, at 15:51, tachekent wrote:

as long as it has the right info for the subclass in it, and not just
the parent inherited across all subclass.

So, I’m wondering if there’s a way to write this so that it will run
caches_constant for subclass, or do I have to include the
caches_constants line in all my subclasses?

The inherited hook as you found below would do the trick. feels a bit
overkill to me - sometimes there is such a thing as too DRY.

I’ve replacing caches_constants with this which seems to work, but I’m
worried I may be overwriting something critical in activerecord:

class RnData < ActiveRecord::Base
def self.inherited(subclass)
subclass.caches_constants
end
end

at the very least call super here or you will be overwriting stuff here.

Fred

The inherited hook as you found below would do the trick. feels a bit
overkill to me - sometimes there is such a thing as too DRY.

Yeah but I have at least 17 subclasses that are basically empty stubs
for looking up the data and setting relationships on a model.

oh, and thanks for the ‘super’ I always wondered what that did :slight_smile: