Forum: Ruby on Rails constant caching, modules and STI

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
tachekent (Guest)
on 2009-02-23 17:52
(Received via mailing list)
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:in
`const_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:in `const_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:in `const_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
Frederick C. (Guest)
on 2009-02-23 18:12
(Received via mailing list)
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
tachekent (Guest)
on 2009-02-23 19:23
(Received via mailing list)
> 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.
tachekent (Guest)
on 2009-02-23 20:17
(Received via mailing list)
oh, and thanks for the 'super' I always wondered what that did :)
This topic is locked and can not be replied to.