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.
C4ceadae4f61dac8ff3ababc3faa6c42?d=identicon&s=25 Felipe Coury (fcoury)
on 2009-05-06 19: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?
96fc3b82ceb54945fecca2fbdddd85a2?d=identicon&s=25 Py Jay (ppjunty)
on 2009-05-06 23: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.