Ruby on rails 当cache_classes=false时,为什么includes-in-Rails引擎初始值设定项会发生故障?

Ruby on rails 当cache_classes=false时,为什么includes-in-Rails引擎初始值设定项会发生故障?,ruby-on-rails,rails-engines,Ruby On Rails,Rails Engines,我有一个引擎,它在初始化器中扩展另一个引擎的类,如下所示: module MyApp class Engine < ::Rails::Engine initializer 'extend Product' do AnotherApp::Product.send :include, MyApp::ProductExtender end end end 这在测试和生产环境中有效,但当config.cache\u clas

我有一个引擎,它在初始化器中扩展另一个引擎的类,如下所示:

module MyApp
    class Engine < ::Rails::Engine
        initializer 'extend Product' do
            AnotherApp::Product.send :include, MyApp::ProductExtender
        end
    end
end
这在测试和生产环境中有效,但当
config.cache\u classes=false
时,当我试图调用ProductExtender定义的东西时,它会向我抛出一个
NoMethodError
,如@product.variations

不用说,看到我所有的测试都通过了,然后在开发过程中被一个错误狠狠地砸了一下,真是令人心寒。当我设置
cache\u classes=true
时,这种情况不会发生,但它让我怀疑自己是否在做不该做的事情

我的问题有两个:为什么会发生这种情况,有没有更好的方法来实现在另一个应用程序对象上扩展/调用方法的功能?


谢谢大家

cache_类实际上有一个误导性的名称:不涉及缓存。如果将此选项设置为false,rails将显式卸载应用程序代码,并在需要时重新加载。这使得您在开发中所做的更改能够生效,而无需重新启动(服务器)进程

在您的情况下,会像ProductExtender一样重新加载AnotherApp::Product,但在重新加载后不会再次触发初始值设定项,因此AnotherApp::Product不会“扩展”


我非常了解这个问题,并最终以cache_classes=true运行我的开发环境,偶尔重新启动服务器。我在引擎/插件上没有太多的开发工作要做,所以这是最简单的方法。

我用
来准备
块而不是初始值设定项来解决这个问题。to_prepare
块在生产中执行一次,在开发中的每个请求之前执行一次,因此似乎满足了我们的需求

当我研究
Rails::Engine
时,它并不明显,因为它继承自
Rails::Railtie::Configuration

因此,与问题中的代码不同,我会:

module MyApp
    class Engine < ::Rails::Engine
        config.to_prepare do
            AnotherApp::Product.send :include, MyApp::ProductExtender
        end
    end
end
模块MyApp
类引擎<::Rails::引擎
config.to_准备做什么
另一个应用程序::Product.send:include,MyApp::ProductExtender
结束
结束
结束

谢谢你的建议,@mosch。你的帖子让我思考了一下,所以我做了更多的研究,最终找到了config.to_prepare块,它似乎可以解决问题,而无需更改cache_类设置(请参阅我提交给自己的问题的答案)。
module MyApp
    class Engine < ::Rails::Engine
        config.to_prepare do
            AnotherApp::Product.send :include, MyApp::ProductExtender
        end
    end
end