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



我想在视图中显示MyModel子类的选择列表。它还不能工作,所以为了检查完整性,我在我的视图中包含了这个:

<%= MyModel.descendants %>

在重新启动服务器后第一次呈现这个页面时,它显示了后代列表(有六个)。所有之后的次,它都显示为空列表[]

哎呀,我有一个require语句在我的初始化:

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

…而且我已经证实他们是被要求的。

@($%&发生什么事了?

我也遇到了同样的问题。通过添加config/initializers/preload_models.rb来解决:

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

希望对大家有所帮助。

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

基本上,在你的第一个请求,rails自动从my_model.rb加载MyModel,然后需要my_models/sub_model.rbSubModel类继承MyModel,后者填充descendants数组。但是,在您的以下请求中,rails再次自动加载MyModel(嘿,您处于开发模式),然后再次需要my_models/sub_model.rb。但是这一次,内核知道它已经加载了这个文件,并且不会再加载它了。

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

这是一个解决方案:

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

这些行可以放在类之外。这应该是足够的(这是对我来说),如果你只有文件在my_models,而不是在子目录。如果你有一些(例如MyModels::Car::Ford),你可能需要把同样的东西放在子模块(在my_models/car.rb)。

我刚刚在每个环境中启用了即时加载:

config.eager_load = true

这对我来说是有效的,即使使用名称空间作为类名。

相关内容

  • 没有找到相关文章

最新更新