为什么我的方法每次都不会覆盖?

时间:2011-03-30 01:54:57

标签: ruby-on-rails ruby metaprogramming

我正在使用Rails 2.3.5。我想要的是"#{Rails.root}/lib/extensions"中的Ruby模块在app启动时加载并包含在控制器和/或模型中。通过在environment.rb

的底部放置类似于以下内容的代码,可以轻松完成
Dir["#{Rails.root}/lib/extensions/*.rb"].each do |file|
    ...... 
    AController.send(:require, file)
    AController.send(:include, constant_of_module_in_file)
end

有效。我可以测试一下。我的模块包括在内。在其中一些模块中,我这样做:

def self.included(klass)
    klass.class_eval { ... overwrite some methods ... }
end

当我用scripts/console测试这段代码时,我得到了我想要的东西:只要我在AController的一个实例上调用该方法,就会调用我的覆盖方法。当我运行webapp并测试应该运行我的覆盖的代码时,情况并非如此。相反,一个有趣的事情发生了:在第一个请求我得到了我期望的(覆盖行为),但后续请求运行我试图覆盖的方法! 为什么?

我以前见过这样的行为,这通常是因为在开发环境中发生的类重新加载。但是,在这种情况下,config.cache_classesconfig.action_controller.perform_caching都是false

任何有关此行为的信息都会有所帮助。我已尝试使用#extend#alias_method_chain,类重新定义等进行各种元编程,但行为总是相同的。

谢谢!

1 个答案:

答案 0 :(得分:1)

如果cache_classes为false,则会在每次请求时卸载并重新加载您的类(因为它们未被缓存)。那就是你用environment.rb射击自己的地方。

如果您只需要文件并在课程中包含所需的模块,则每次都会应用覆盖:

require file
class AController < ApplicationController
  include constant_of_module_in_file
end

编辑:归功于Xavier Holt,我在发布答案后才看到他的评论!