Problem caching Model instances on a constant in Rails

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?

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 forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs