如何从初始化程序扩展类并在开发环境中重新加载?

我通过包含一个模块来扩展一个类(在插件中),这是在初始化器中完成的。

require 'qwerty/core/user' User.send :include, Qwerty::Core::Extensions::User 

但是在开发之前,每个请求(以及在控制台中调用reload!之后)都会重新加载所有模型,但由于初始化程序不会再次运行,因此不包含该模块。 留下一个带有“缺少部件”的模型。

因为模型是在插件中,所以直接在类中包含代码似乎是明智的,这是通常的方法。

现在我只是添加了一个before_filter,它包含了在开发环境中的模块。 但我已复制/粘贴并在初始化程序和应用程序控制器中有重复的代码

  # Class extensions in initalizers are over-writtern each request def development_loading if RAILS_ENV == 'development' User.send :include, Qwerty::Core::Extensions::User end end 

有没有更好的办法?

作为旁注,插件是我的,所以我可以添加代码,但模块中保存的扩展可能并不总是存在…

的environment.rb

 config.to_prepare do User.send :include, Qwerty::Core::Extensions::User end 

代码是块在开发模式中的每个请求之前运行,并且在生产模式下运行一次。

在Rails 3.x中,您可以配置每次重新加载时运行的块(在开发模式下,或者在config.cache_classes = false )。 这将在初始化器中:

 ActionDispatch::Callbacks.to_prepare do # configure stuff or initialize end 

比接受的解决方案稍微优雅一点,因为它可以放在初始化器中:

 require 'dispatcher' Dispatcher.to_prepare do # stuff that needs to happen once per initialization end 

起初我打算建议在开发模式下将一个“开发”目录添加到加载路径的前面,这样你的修订版总会先重新加载……但是后来我发现你说了一些令人困惑的东西。

您尝试扩展的模型。 它是插件吗? 默认情况下,在开发模式下不应该重新加载插件,除非应用程序通过设置Config.reload_plugins?明确说明它们应该在其配置中Config.reload_plugins? 为假。

但是,如果由于某种原因,你的插件仍在重新加载并且你想要它,你可以将它放在你的插件的init.rb中明确说它不应该重新加载:

 Dependencies.load_once_paths << lib_path 

有关更多详细信息,请参阅Configuration类上的Rails文档: http : //api.rubyonrails.org/classes/Rails/Configuration.html#M002536

为什么使用初始化程序来包含function?

请尝试以下方法:

 require 'qwerty/core/user' class User < ActiveRecord::Base include Qwerty::Core::Extensions::User # bla bla end