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

时间:2009-10-07 12:55:38

标签: ruby-on-rails ruby

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

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

有更好的方法吗?

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

5 个答案:

答案 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