gpt4 book ai didi

ruby-on-rails - Zeitwerk + Rails 6.1 带有模型和命名空间子类, "earlier autoload discarded"

转载 作者:行者123 更新时间:2023-12-03 07:59:42 24 4
gpt4 key购买 nike

在对 SO 和 a very similar issue 进行研究之后在 Rails 的 GitHub issues 中,我仍然不清楚出了什么问题。我的命名空间模型子类不是急切加载的,但我相信它们已在正确的位置正确声明。

它们似乎是自动加载并且可以访问的,但是每一个在实例化之前都不会出现在父类的子类中。

父模型:

# /app/models/queued_email.rb

class QueuedEmail < ApplicationRecord
end

我的命名空间子类模型(有十几个):

# /app/models/queued_email/comment_notification.rb

class QueuedEmail::CommentNotification < QueuedEmail
end

# or alternatively (this also doesn't eager load):

module QueuedEmail
class CommentNotification < QueuedEmail
end
end

来自Rails.autoloaders.log!的相关消息(在config/application.rb中)

<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="29734c405d5e4c5b42695b4840455a0744484047" rel="noreferrer noopener nofollow">[email protected]</a>: autoload set for QueuedEmail, to be autovivified from /vagrant/rails_app/app/models/queued_email
<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="a7fdc2ced3d0c2d5cce7d5c6cecbd489cac6cec9" rel="noreferrer noopener nofollow">[email protected]</a>: earlier autoload for QueuedEmail discarded, it is actually an explicit namespace defined in /vagrant/rails_app/app/models/queued_email.rb
<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="752f101c010210071e3507141c19065b18141c1b" rel="noreferrer noopener nofollow">[email protected]</a>: autoload set for QueuedEmail, to be loaded from /vagrant/rails_app/app/models/queued_email.rb

如果我打开rails console并调用子类,我什么也得不到:

> QueuedEmail
=> QueuedEmail (call 'QueuedEmail.connection' to establish a connection)
> QueuedEmail.subclasses
[]

但是……子类是可以访问的。

> QueuedEmail::CommentNotification
=> QueuedEmail::CommentNotification(id: integer...)
> QueuedEmail::CommentNotification.superclass
=> QueuedEmail(id: integer...)
> QueuedEmail.subclasses
=> [QueuedEmail::CommentNotification(id: integer...)]

在代码中实例化每个子类之前,我在子类中什么也得不到。我的 app/models 文件夹是否组织不正确,或者我的子类命名不正确?

最佳答案

让我首先解释一下日志消息。

Zeitwerk 扫描项目,在找到 queued_email.rb 之前发现了一个名为 queued_email 的目录。因此,作为一个工作假设,它假设 QueuedEmail 是一个包含其信息的隐式命名空间。当它看到 queued_email.rb 并说“等等,这实际上是一个显式命名空间”时,这个假设后来变得无效。因此它取消了隐式设置,并重新定义它以加载显式命名空间。

现在,我们来看看子类。

当应用程序不预先加载时,文件仅按需加载。例如,如果您加载QueuedEmail,并且app/models/queued_email递归地有24个文件,则在使用它们之前不会加载它们。

当一个类被子类化时,subclasses 返回的集合将被填充。但在加载子类之前,您不知道该类已被子类化。因此,在延迟加载环境中,子类一开始就是空的。如果您加载 1 个子类,它将包含该子类,但不会包含其余子类,直到它们最终全部加载为止。

如果您需要子类以使应用程序正常运行,从 Zeitwerk 2.6.2 开始,您可以将其扔给初始值设定项

# config/initializers/eager_load_queued_email.rb
Rails.application.config.to_preprare do
Rails.autoloaders.main.eager_load_dir("#{Rails.root}/app/models/queued_email")
end

关于ruby-on-rails - Zeitwerk + Rails 6.1 带有模型和命名空间子类, "earlier autoload discarded",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74724066/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com