我在我的一个模型上为 Rails 应用程序使用单表继承 (STI),并且在将模型对象存储在常量上时遇到问题。我已将问题隔离到一个示例项目中并将其提交到 GitHub:http: //github.com/fcoury/rails-sti-caching
我要做的是在初始化程序(在 Rails/config/initializers/
目录中)上加载模型实例(在本例中为 Music 模型,通过 STI 从 Media 模型继承)并将其保持为常量:
MUSIC_CACHE = Hash.new
Music.all.each { |m| MUSIC_CACHE[m.id] = m }
我有一个示例控制器,它执行以下操作:
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
以及与之相伴的观点:
<h1 id="music">Music</h1>
<ul>
<% for m in @musics %>
<li><%= m.name %> - <%= m.file %></li>
<% end %>
</ul>
<pre><%=h @debug.join("\n") %></pre>
这段代码第一次运行时,<pre>
标签上的输出是这样的:
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
但是,如果我只是重新加载页面,则会输出以下内容:
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?
有谁知道这个错误背后的原因?