问题 在开发模式下的每个请求上重新加载*文件后,如何挂钩到Rails *?


我正在努力 宝石 在ActiveRecord模型上设置属性(例如 table_name)动态地基于用户配置选项。

我有一个初始化器来实现这一目标。然而,我的问题是在开发模式下,这些类被重新加载,因此它们不会维护这些值。

所以我以为我会使用一个铁路来挂钩重新加载这些文件并在模型上再次运行我的配置。然而我的问题是 config.to_prepare 在铁路上似乎跑了之前 reload! 实际上发生了。我可以通过一些记录来证明这一点:

module MyMod
  class Railtie < Rails::Railtie

    config.to_prepare do
      Rails.logger.debug("Contact object_id: #{Contact.object_id}")
    end
  end
end

如果我加载我的控制台,我得到第一个日志:

Contact object_id: 2202692040

如果我检查 Contact.object_id 它匹配:

Contact.object_id  #=> 2202692040

然后我 reload!

reload!

我的Rails记录器 to_prepare 日志:

Contact object_id: 2202692040

所以它仍然有旧的object_id,但是当我在控制台中检查它时:

Contact.object_id  #=> 2197355080

哪个是新加载的类对象id。

那我该怎么办? to_prepare 跑步  文件重新加载?运用 Rails 3.0.10

更新

我也试过手动将此动作附加到 after_prepare 回调 ActionDispatch::Callbacks 像这样:

initializer "apartment.init" do
  ActionDispatch::Callbacks.set_callback(:prepare, :after) do
    Rails.logger.debug("Contact object_id: #{Contact.object_id}")
  end
end

确实在它之后运行回调 config.to_prepare 但它似乎仍然会发生 before 重新加载文件...我得到与上面相同的行为。


3972
2017-09-21 18:26


起源

你尝试过类似的东西吗? stackoverflow.com/questions/5308970/... - montrealmike


答案:


写一个初始化器,如果 cache_classes 是 false,用途 ActionDispatch::Reloader 设置一个 to_prepare 运行gem的安装例程的回调。

initializer 'foobar.install' do
  if Rails.configuration.cache_classes
    FooBar.install!
  else
    ActionDispatch::Reloader.to_prepare do
      FooBar.install!
    end
  end
end

它可以在控制台中使用 reload! 方法和Rack应用程序服务器。

:-)


12
2017-07-10 14:51



看起来 to_prepare  被称为一次 当类被缓存时,你可以这样做:{ActionDispatch :: Reloader.to_prepare do FooBar.install!结束 } - hlascelles
初始化程序对我不起作用,但我删除了它并且它有效,很难在文档中找到这样的内容,谢谢 - juanpastas
对于新的Rails版本5.x,我们需要使用 ActiveSupport::Reloader.to_prepare 代替 ActionDispatch::Reloader.to_prepare - Blue Smith


我相信Rails重新加载器只会解开常量。在应用程序中引用常量时,模型会重新加载自动加载。

在你的回调中,我认为你必须通过引用所有模型来手动触发负载。也许你的宝石可以保留包含它的所有模型的列表,然后只需引用常量来自动加载它们......

model_names.each { |model_name| model_name.constantize }

您可以使用构建列表 self.included

module MyGem
  self.included(base)
    @model_names ||= Set.new
    @model_names += base.to_s
  end
end

0
2018-03-22 21:38



有趣!谢谢。我会调查一下 - brad