我通过包含一个模块来扩展一个类(在插件中),这是在初始化器中完成的。
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
有更好的方法吗?
作为旁注,插件是我的,所以我可以添加代码,但模块中保存的扩展可能并不总是存在...
答案 0 :(得分:11)
的environment.rb
config.to_prepare do
User.send :include, Qwerty::Core::Extensions::User
end
代码是块在开发模式下的每个请求之前运行,并且一次在生产模式下运行。
答案 1 :(得分:6)
在Rails 3.x中,您可以配置每次重新加载时运行的块(在开发模式下,或config.cache_classes = false
时)。这将在初始化器中进行:
ActionDispatch::Callbacks.to_prepare do
# configure stuff or initialize
end
答案 2 :(得分:3)
比接受的解决方案稍微优雅一点,因为它可以放在初始化器中:
require 'dispatcher'
Dispatcher.to_prepare do
# stuff that needs to happen once per initialization
end
答案 3 :(得分:1)
首先,我会建议在开发模式下将“开发”目录添加到加载路径的前面,这样你的修订版总是会先重新加载......但是后来我发现你说过令人困惑的事情。
您尝试扩展的模型。它位于插件中?默认情况下,在开发模式下,插件不会假设重新加载,除非应用程序通过设置Config.reload_plugins?
明确表示它们应该在其配置中为假。
但是,如果由于某种原因,您的插件仍在重新加载并且不想要它,您可以将它放在插件的 init.rb 中说不应该重装:
Dependencies.load_once_paths << lib_path
有关更多详细信息,请参阅Configuration类上的Rails文档: http://api.rubyonrails.org/classes/Rails/Configuration.html#M002536
答案 4 :(得分:0)
为什么使用初始值设定项来包含功能?
请尝试以下方法:
require 'qwerty/core/user'
class User < ActiveRecord::Base
include Qwerty::Core::Extensions::User
# bla bla
end