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

发布于 2024-11-04 19:04:41 字数 412 浏览 0 评论 0原文

我想在视图中显示 MyModel 子类的选择列表。它尚未工作,因此为了进行健全性检查,我将其包含在我的视图中:

<%= MyModel.descendants %>

重新启动服务器后第一次渲染此页面时,它显示了后代列表(有六个)。随后的所有时间,它都显示为空列表[]

FWIW,我的初始化程序中有一个 require 语句:

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

...并且我已经验证它们是必需的。

@($%& 是怎么回事?

I want to display a selection list of MyModel subclasses in a view. It's not working yet, so for sanity checking, I included this in my view:

<%= MyModel.descendants %>

The first time I render this page after re-starting the server, it shows the list of descendants (there are six). All subsequent times, it shows up as an empty list [].

FWIW, I have a require statement in my initializers:

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

... and I've verified that they're getting required.

What the @($%& is going on?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

回首观望 2024-11-11 19:04:41

我也有同样的问题。通过添加 config/initializers/preload_models.rb 解决了这个问题:

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

希望对某人有帮助。

I had the same problem. Solved it by adding a config/initializers/preload_models.rb with:

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

Hope that helps somebody.

似狗非友 2024-11-11 19:04:41

当您使用 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 中) 。

When you use require, even if your my_model.rb gets reloaded, the kernel won't require your subclasses .rb files because they have already been loaded. You'd have to go through rails autoload.

Basically, on your first request, rails autoloads MyModel from my_model.rb, which then requires my_models/sub_model.rb. The SubModel class inherits MyModel, which populates the descendants array.
On your following requests, though, rails autoloads MyModelagain (hey, you're in dev mode), which then requires my_models/sub_model.rb again. But this time, the kernel knows it had already loaded this file and won't load it again.

I ran into this problem one hour ago, which lead me to your post, and to find a solution. What we need is rails to autoload subclasses everytime your main class is called.

Here is a solution :

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

These lines could probably be put outside of the class. That should be enough (it is for me) if you only have files in my_models and not in subdirectories. If you have some (for example MyModels::Car::Ford, you may need to put the same kind of stuff in the submodules (in my_models/car.rb).

挖个坑埋了你 2024-11-11 19:04:41

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

config.eager_load = true

即使在使用类名的命名空间时,这对我也有用

I just enabled eager loading in each environment:

config.eager_load = true

This worked for me even when using namespaces for class names.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文