我正在尝试编写一个扩展InheritedResources的插件。
具体来说,我想重写一些默认助手。
而且我希望它在安装后“正常工作”,不对应用程序代码进行任何更改。
该功能在需要包含在正确位置的模块中提供。 问题是在哪里? :)
第一次尝试是在我的插件的init.rb中做到这一点:
InheritedResources::Base.send :include, MyModule它在生产中工作,但在开发中失败,因为InheritedResource :: Base声明为unloadable ,因此它的代码在每个请求上重新加载。 所以我的模块是第一个请求,然后它就消失了。
InheritedResource :: Base被任何使用它的控制器再次“拉入”:
Class SomeController < InheritedResource::Base但是没有代码可以“拉入”我的扩展模块,因为它除了init.rb之外没有被引用,而init.rb 没有在每个请求上重新加载
所以现在我只是手动将模块包含在需要它的每个控制器中。 我甚至无法在ApplicationController中包含它一次,因为InheritedResources继承它,因此它将覆盖任何更改。
更新
我不是在寻找关于如何'猴子补丁'的建议。 该扩展正在生产中非常好。 我的问题是如何在加载InheritedResources之后准确抓住时刻将我的扩展插入其中:)
UPDATE2
另一种澄清的尝试:
事件的顺序是
a)导轨加载插件。 我的插件在inherited_resources之后加载并修补它。 b)提供开发模式请求并且有效 c)rails卸载所有'unloadable'代码,其中包括所有应用程序代码和inherited_resources d)另一个请求进来 e)rails负载控制器,它继承自继承的资源 f)rails加载继承自application_controller的继承资源 g)rails加载application_contrller(或者可能是它已经在此阶段加载,不确定) g)请求失败,因为没有人加载我的插件来修补inherited_resources。 插件init.rb文件不会重新加载我需要抓住g和h之间的时间点
I'm trying to write a plugin that will extend InheritedResources.
Specifically I want to rewrite some default helpers.
And I'd like it to "just work" once installed, w/o any changes to application code.
The functionality is provided in a module which needs to be included in a right place. The question is where? :)
The first attempt was to do it in my plugin's init.rb:
InheritedResources::Base.send :include, MyModuleIt works in production, but fails miserably in development since InheritedResource::Base declared as unloadable and so its code is reloaded on each request. So my module is there for the first request, and then its gone.
InheritedResource::Base is 'pulled' in again by any controller that uses it:
Class SomeController < InheritedResource::BaseBut no code is 'pulling in' my extension module since it is not referenced anywhere except init.rb which is not re-loaded on each request
So right now I'm just including the module manually in every controller that needs it which sucks. I can't even include it once in ApplicationController because InheritedResources inherites from it and so it will override any changes back.
update
I'm not looking for advice on how to 'monkey patch'. The extension is working in production just great. my problem is how to catch moment exactly after InheritedResources loaded to stick my extension into it :)
update2
another attempt at clarification:
the sequence of events is
a) rails loads plugins. my plugin loads after inherited_resources and patches it. b) a development mode request is served and works c) rails unloads all the 'unloadable' code which includes all application code and also inherited_resources d) another request comes in e) rails loads controller, which inherites from inherited resources f) rails loads inherited resources which inherit from application_controller g) rails loads application_contrller (or may be its already loaded at this stage, not sure) g) request fails as no-one loaded my plugin to patch inherited_resources. plugin init.rb files are not reloadedI need to catch the point in time between g and h
最满意答案
环境文件中的Rails :: Configuration config允许在开发模式下的每个请求之前运行的调度程序上注册回调,或者在生产模式下注册一次。
config.to_prepare do # do something here end问题是,我不认为你的插件在运行init.rb文件时可以访问config 。 这是一种直接在调度程序中注册回调的方法。 把它放在init.rb文件中。
require 'dispatcher' ::Dispatcher.to_prepare do puts "hi there from a plugin" end警告:我不知道这可能有什么副作用。 如果可能,尝试访问config并以正确的方式注册回调。
The Rails::Configuration, config in the environment files, allows registering a callback on the dispatcher that runs before each request in development mode, or once when in production mode.
config.to_prepare do # do something here endThe problem is, I don't think your plugin has access to config when the init.rb file is run. Here is a way to register your callback directly in the dispatcher. Just put this in the init.rb file.
require 'dispatcher' ::Dispatcher.to_prepare do puts "hi there from a plugin" endWarning: I don't know what side effects this may have. If possible, try to get access to config and register the callback tha right way.
更多推荐
发布评论