gpt4 book ai didi

ruby-on-rails - 包含从插件到 Controller 的方法

转载 作者:数据小太阳 更新时间:2023-10-29 07:17:14 26 4
gpt4 key购买 nike

使用 Rails 2.3.11,我正在为 Redmine 创建一个插件,将 添加方法ApplicationController

我在插件中创建了以下模块:

module ApplicationControllerPatch
def self.included(base) # :nodoc:
base.class_eval do
rescue_from AnException, :with => :rescue_method

def rescue_method(exception)
...
end
end
end
end

现在,如果我将这个模块直接包含到 application_controller.rb 文件中,如下所示:

class ApplicationController < ActionController::Base
include ApplicationControllerPatch

...
end

一切正常,但是我想通过从插件本身包含这个模块来避免编辑核心源代码。到目前为止,如果我这样做:

ApplicationController.send(:include, ApplicationControllerPatch)

直接来自这个模块文件(位于插件文件夹中)。这将为请求正确加载,然后它会被 Controller 覆盖(我猜)。

实现这个的方法是什么?

最佳答案

一种常见的模式是在插件的 init.rb 中使用 Dispatcher.to_prepare。这是必需的,因为在开发模式下(或者通常如果 config.cache_classes = false)Rails 会在每个请求之前重新加载所有类以获取更改,而无需每次都完全重新启动应用程序服务器。

然而,这意味着您必须在类重新加载后再次应用补丁,因为 Rails 无法知道稍后注入(inject)了哪些模块。使用 Dispatcher.to_prepare 就可以做到这一点。 block 中定义的代码在生产模式下执行一次,在开发模式下在每个请求之前执行一次,这使其成为猴子补丁核心类的首要位置。

这种方法的好处是您可以让您的插件自包含并且不需要更改周围应用程序中的任何内容。

把它放在你的 init.rb 里,例如vendor/plugins/my_plugin/init.rb

require 'redmine'

# Patches to the Redmine core.
require 'dispatcher'

Dispatcher.to_prepare do
ApplicationController.send(:include, MyPlugin::ApplicationControllerPatch) unless ApplicationController.include?(RedmineSpentTimeColumn::Patches::IssuePatch)
end

Redmine::Plugin.register :my_plugin do
name 'My Plugin'
[...]
end

您的补丁应始终在以您的插件命名的模块内命名空间,以免遇到定义相同模块名称的多个插件的问题。然后将补丁放入lib/my_plugin/application_controller_patch.rb。这样,它就会被 Rails Autoloader 自动拾取。

将其放入 vendor/plugins/my_plugin/lib/my_plugin/application_controller_patch.rb

module MyPlugin
module ApplicationControllerPatch
def self.included(base) # :nodoc:
base.class_eval do
rescue_from AnException, :with => :rescue_method

def rescue_method(exception)
[...]
end
end
end
end
end

关于ruby-on-rails - 包含从插件到 Controller 的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7936023/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com