RoR:MyModel.descendants在第一次调用后在视图中返回[]?

fea*_*ool 9 activerecord ruby-on-rails-3

我想在视图中显示MyModel子类的选择列表.它还没有工作,所以为了进行健全性检查,我把它包括在我的观点中:

<%= MyModel.descendants %>
Run Code Online (Sandbox Code Playgroud)

第一时间,我渲染后重新启动服务器这个页面,它显示后裔的名单(有六个).随后的所有时间,它都会显示为空列表[].

FWIW,我require在初始化器中有一个声明:

Dir[Rails.root.join("app/models/my_models/**/*.rb").to_s].each {|f| require f}
Run Code Online (Sandbox Code Playgroud)

......我已经证实他们已经被要求了.

@($%&正在发生什么?

小智 9

我有同样的问题.解决它添加一个config/initializers/preload_models.rb:

Dir[Rails.root + 'app/models/*.rb'].map {|f| File.basename(f, '.*').camelize.constantize }
Run Code Online (Sandbox Code Playgroud)

希望能帮到别人.


Wam*_*Wam 7

当您使用require时,即使my_model.rb重新加载,内核也不会要求您的子类.rb文件,因为它们已经被加载.你必须通过rails autoload.

基本上,你的第一个要求,导轨自动加载MyModelmy_model.rb,然后要求my_models/sub_model.rb.的SubModel类继承MyModel,它填充descendants阵列.但是,在您的后续请求中,rails MyModel再次自动加载(嘿,您处于开发模式),然后my_models/sub_model.rb再次需要.但是这一次,内核知道它已经加载了这个文件,并且不会再加载它.

我在一小时前遇到了这个问题,这引导我到你的帖子,找到解决方案.我们需要的是每次调用主类时都要自动加载子类.

这是一个解决方案:

class MyModel
  Dir[File.join(File.dirname(__FILE__),"my_models","*.rb")].each do |f|
    MyModels.const_get(File.basename(f,'.rb').classify)
  end
end
Run Code Online (Sandbox Code Playgroud)

这些行可能会被放在课堂之外.如果您只有文件my_models而不是子目录中的文件应该足够(对我而言).如果你有一些(例如MyModels::Car::Ford,你可能需要在子模块中放入相同类型的东西(in my_models/car.rb).


msc*_*ven 7

我只是在每个环境中启用了热切加载:

config.eager_load = true

即使在为类名使用名称空间时,这也适用于我.