J'utilise l'héritage de table unique (STI) sur l'un de mes modèles pour une application Rails et j'ai des problèmes pour stocker des objets de modèle sur une constante. J'ai isolé le problème dans un exemple de projet et l'ai soumis à GitHub: http://github.com/fcoury/rails-sti-cachingProblème de mise en cache Instances de modèle sur une constante dans Rails
Ce que j'essaie de faire est de charger une instance de modèle (dans ce cas, un modèle de musique, qui hérite du modèle Media via STI) sur un initialiseur (dans Rails répertoire de /config/initializers/
) et le maintenir sur une constante:
MUSIC_CACHE = Hash.new
Music.all.each { |m| MUSIC_CACHE[m.id] = m }
et j'ai un contrôleur d'échantillon qui effectue les opérations suivantes:
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
et en vue d'aller avec elle:
<h1 id="music">Music</h1>
<ul>
<% for m in @musics %>
<li><%= m.name %> - <%= m.file %></li>
<% end %>
</ul>
<pre><%=h @debug.join("\n") %></pre>
La première fois que ce code fonctionne, la sortie sur l'étiquette <pre>
est la suivante:
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
Cependant, si je recharge seulement la page, voici ce qui sera émis:
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?
Est-ce que quelqu'un sait la raison derrière cette erreur?
Pourriez-vous obtenir l'exception Ruby appropriée avec la trace de la pile au lieu de '' Vous avez un objet nul quand vous ne l'attendiez pas! ''? – pts