我正在开发一个使用引擎的 Rails 应用程序。我正在使用初始化程序来配置我的引擎 Controller 之一,以便它将触发主机应用程序中的操作。代码看起来像这样:
# config/initializers/my_engine.rb
MyEngine::SomeController.after_filter proc {
# Do something in the host app
}, :only => :update
这在生产中运行良好,但在开发模式下,proc 仅在第一个请求时调用。这是因为类正在重新加载并且此配置丢失,因为它存储在类变量中。 (例如,
MyEngine::SomeController
是从它所在的文件中重新加载的,并且由于 after_filter
没有在那里声明,所以它不会重新添加。)一些 Rails 背景
在开发模式下,Rails 使用以下加载策略:
app
中的代码假设您正在积极更改目录,则每次请求都会重新加载目录。 lib
中的代码目录,以及 config/initializer
文件,已加载 一次 ,当应用程序启动时。 初始化文件通常用于配置 gems。过去,gem 的代码大多位于
lib
目录,因此运行一次配置就足够了。引擎如何改变事物
然而,Rails 引擎在
app
中有代码。目录: Controller 、模型等。这些文件在每次请求时以开发模式重新加载。因此,像我上面的示例这样的配置丢失了。输入 to_prepare
Rails 提供
config.to_prepare
专门解决这个问题:它在生产中运行一次,并在开发中的每个请求上运行。例如,我们在 application.rb 中有这个,它工作正常:
config.to_prepare do
# set up class variables (after_filters, etc)
end
但是,如果我必须将所有引擎的配置放入
application.rb
,这违背了 config/initializers
的观点使事情井井有条。因此,对于我的引擎中的任何类配置
app
目录,我想将该代码放在 config/initializers
下的文件中.这是我的问题。
config
进入初始化文件的范围。我想应该是 Rails.application.config
.是对的吗? to_prepare
block ?恐怕多次调用它会覆盖以前的 block 。 更新
正如@Frederick Cheung 所说,
Rails.application.config.to_prepare
在 config/initializer
中工作文件,并且可以在各种文件中根据需要使用尽可能多的这些文件;每个调用都将其 block 附加到一个数组中,因此不会覆盖任何内容。所以这个问题的解决方案是:
# config/initializers/my_engine.rb
Rails.application.config.to_prepare do
MyEngine::SomeController.after_filter proc {
# Do something in the host app
}, :only => :update
end
一件看起来仍然很奇怪的事情:我预计
to_prepare
要在 上调用的 block 每个请求 在开发模式下,但似乎每隔 3 次左右随机调用一次。我添加了 block :Rails.application.config.to_prepare do
Rails.logger.info "Running the prepare block!"
end
...重新启动我的应用程序,并刷新页面九次。我只在第 1 次、第 5 次、第 7 次和第 9 次请求中看到了消息。我不确定是什么解释了这种行为,但它确实解释了为什么我的代码 没有
to_prepare
在开发中间歇性地工作。
最佳答案
没有什么可以阻止您在 app/models 中的文件中执行初始化代码。
例如
class MyClass
def self.run_me_when_the_class_is_loaded
end
end
MyClass.run_me_when_the_class_is_loaded
MyClass.run_me... 将在加载类时运行 .... 这是我们想要的,对吧?
不确定它是否是 Rails 的方式......但它非常简单,并且不依赖于 Rails 的风向。
关于ruby-on-rails - 如何防止我的初始化程序配置在开发模式中丢失?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8895103/