在开发模式下,如何在每个请求重新加载文件后 * 挂接到 Rails? [英] How do I hook into Rails *after* files are reloaded on each request in development mode?

查看:39
本文介绍了在开发模式下,如何在每个请求重新加载文件后 * 挂接到 Rails?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个 gem,它在 ActiveRecord 模型上设置属性(例如 table_name) 动态基于用户配置选项.

I'm working on a gem that sets properties on ActiveRecord models (such as table_name) dynamically based on a user config option.

我有一个可以实现这一点的初始化程序.然而,我的问题是在开发模式下,这些类会重新加载,因此它们不会维护这些值集.

I have an initializer that achieves this. My problem however is that in dev mode, these classes are reloaded, so they don't maintain these values set.

所以我想我会使用 railtie 挂钩到重新加载这些文件的位置,并在模型上再次运行我的配置.然而,我的问题是 Railtie 中的 config.to_prepare 似乎在 reload! 实际发生之前运行.我可以通过一些日志来证明这一点:

So I thought I'd use a railtie to hook into the point where these files are reloaded and run my config again on the models. My problem however is that config.to_prepare in the railtie appears to run before the reload! actually takes place. I can prove this with a bit of logging:

module MyMod
  class Railtie < Rails::Railtie

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

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

if I load up my console, I get the first log:

Contact object_id: 2202692040

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

If I check Contact.object_id it matches up:

Contact.object_id  #=> 2202692040

然后我重新加载!

reload!

来自我的 to_prepare 日志的 Rails 记录器:

Rails logger from my to_prepare logs:

Contact object_id: 2202692040

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

So it still has the old object_id, but when I check it in the console:

Contact.object_id  #=> 2197355080

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

Which is the newly loaded class object id.

那么如何让 to_prepare 在文件重新加载后 运行?使用 Rails 3.0.10

So how do I get to_prepare to run after the files are reloaded? Using Rails 3.0.10

我还尝试手动将此操作附加到 ActionDispatch::Callbacks 上的 after_prepare 回调,如下所示:

I've also tried manually attaching this action to the after_prepare callback on the ActionDispatch::Callbacks like so:

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 文件重新加载......我得到与上面相同的行为.

It does indeed run the callback after the config.to_prepare but it still appears to happen before the files are reloaded... I get the same behaviour as above.

推荐答案

编写一个初始化程序,如果 cache_classesfalse,则使用 ActionDispatch::Reloader 设置一个 to_prepare 回调运行您的 gem 的安装例程.

Write an initializer that, if cache_classes is false, uses ActionDispatch::Reloader to set a to_prepare callback that runs your gem's installation routine.

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

它既可以在带有 reload! 方法的控制台中运行,也可以在 Rack 应用服务器中运行.

It'll work both in the console with the reload! method and in the Rack application server.

这篇关于在开发模式下,如何在每个请求重新加载文件后 * 挂接到 Rails?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆