Forum: Ruby on Rails Problem caching Model instances on a constant in Rails

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.
Felipe C. (Guest)
on 2009-05-06 21:24
I am using Single-Table Inheritance (STI) on one of my models for a
Rails App and I am having problems storing model objects on a constant.
I have isolated the problem into a sample project and submitted it to
GitHub: http://github.com/fcoury/rails-sti-caching

What I am trying to do is loading a model instance (in this case a Music
model, that inherits from the Media model via STI) on an initializer (in
Rails' `/config/initializers/` directory) and keep it on a constant:

    MUSIC_CACHE = Hash.new
    Music.all.each { |m| MUSIC_CACHE[m.id] = m }

And I have a sample controller that does the following:

    class MusicsController < ApplicationController
      def index
        require 'pp'
        pp MUSIC_CACHE
        @debug = []
        MUSIC_CACHE.each_pair do |k, v|
          music = Music.find(k)
          d "Object for Music.find(#{k})  => class: #{music.class} -
class obj_id: #{music.class.object_id} - #{music.inspect}"
          d "Object for MUSIC_CACHE[#{k}] => class: #{v.class} - class
obj_id: #{v.class.object_id} - #{v.inspect}"

          begin
            d "  - Music.is_a?(Media) => #{v.is_a?(Media)}"
            d "  - Try to call name   => #{v.name}"
          rescue
            d "*** Error raised:\n#{$!}"
          end
        end

        @musics = Music.all
      end

      def d(s)
        puts s
        @debug << s
      end
    end

And a view to go with it:

    <h1 id="music">Music</h1>

    <ul>
      <% for m in @musics %>
      <li><%= m.name %> - <%= m.file %></li>
      <% end %>
    </ul>

    <pre><%=h @debug.join("\n") %></pre>

The first time this code runs, the output on the `<pre>` tag is this:

      Object for Music.find(2)  => class: Music - class obj_id: 13067420
- #<Music id: 2, name: "5th Symphony", file: "5s.mp3", type: "Music",
created_at: "2009-05-06 16:31:41", updated_at: "2009-05-06 16:31:41">
      Object for MUSIC_CACHE[2] => class: Music - class obj_id: 13067420
- #<Music id: 2, name: "5th Symphony", file: "5s.mp3", type: "Music",
created_at: "2009-05-06 16:31:41", updated_at: "2009-05-06 16:31:41">
        - Music.is_a?(Media) => true
        - Try to call name   => 5th Symphony

However, if I just reload the page, here's what gets outputted:

    Object for Music.find(2)  => class: Music - class obj_id: 18452280 -
#<Music id: 2, name: "5th Symphony", file: "5s.mp3", type: "Music",
created_at: "2009-05-06 16:31:41", updated_at: "2009-05-06 16:31:41">
    Object for MUSIC_CACHE[2] => class: Music - class obj_id: 13067420 -
#<Music id: 2, name: "5th Symphony", file: "5s.mp3", type: "Music",
created_at: "2009-05-06 16:31:41", updated_at: "2009-05-06 16:31:41">
      - Music.is_a?(Media) => false
    *** Error raised:
    You have a nil object when you didn't expect it!
    You might have expected an instance of Array.
    The error occurred while evaluating nil.include?

Does anyone know the rationale behind this error?
Py J. (Guest)
on 2009-05-07 01:53
at first looks like the old problem of rails reloading
the classes and not recognizing the objects in memory
anymore. try set "config.cache_classes" to true in your
development.rb file or run in production mode.
This topic is locked and can not be replied to.