如何让我的宝石自成一体,无需编辑任何核心源代码Rails? [英] How to keep my gem self-contained without having to edit any core source Rails?
问题描述
我想添加一个过滤器到 ApplicationController
,但我想在我的宝石内完成。
我想避免的是:
class ApplicationController < ActionController :: Base
包括MyGem
end
我不想那样。我不希望在源代码中包含我的模块。
我遇到了问题。
以下是相关代码:
lib / correlation_id / controller_extension
module CorrelationId
module ControllerExtension
def self.included(klass)
klass.class_eval do
after_filter:pass_correlation_id
结束
结束
def pass_correlation_id
correlation_id = request.headers ['Correlation-ID'] || SecureRandom.uuid
headers ['Correlation-ID'] = correlation_id
end
end
end
ApplicationController.send:include,CorrelationId :: ControllerExtension
lib / correlation_id.rb $ b
require'correlation_id / controller_extension'
模块CorrelationId
结束
现在,当我进入 test / dummy
目录时,这是我的宝石测试栏应用程序,我尝试使用 rails s
来启动服务器,并且出现以下错误:
/correlation_id/lib/correlation_id/controller_extension.rb:17:in`< top(required)>':未初始化的常量ApplicationController(NameError)
我很明显在引用ApplicationController的时候遇到了问题,以便对其进行修补。
我如何管理这个?我希望我的宝石自成一体。 下面的代码有效。我所做的是过早地用适当的继承创建 ApplicationController
。请注意,很多人使用 rails-api
gem,所以我将它们考虑在内以确保它可以工作。
另外,请注意:您必须从类继承,否则 ApplicationController
将是一个通常的类了解 after_filter
是什么。
模块CorrelationId
模块ControllerExtension
def self.included(klass)
klass.class_eval do
after_filter:pass_correlation_id
end
end
$ b $ def pass_correlation_id
correlation_id = request.headers ['Correlation-ID'] || SecureRandom.uuid
headers ['Correlation-ID'] = correlation_id
end
def self.base_controller_inheritance
如果Gem :: Specification.find_all_by_name('rails-api ')。任何?
ActionController :: API
else
ActionController :: Base
end
end
end
end
class ApplicationController< CorrelationId :: ControllerExtension.base_controller_inheritance
include CorrelationId :: ControllerExtension
end
I想象一下可能有更好的方法来检查它们是否使用 ActionController :: API
,如果是的话,请分享一下,但截至目前,这似乎是最稳定的方式做到这一点。
I want to add a filter to the ApplicationController
but I want to do it within my gem.
What I want to avoid is the following:
class ApplicationController < ActionController::Base
include MyGem
end
I do not want that. I don't want to have to include my module in the source code.
I am having issues though.
Here is the relevant code:
lib/correlation_id/controller_extension
module CorrelationId
module ControllerExtension
def self.included(klass)
klass.class_eval do
after_filter :pass_correlation_id
end
end
def pass_correlation_id
correlation_id = request.headers['Correlation-ID'] || SecureRandom.uuid
headers['Correlation-ID'] = correlation_id
end
end
end
ApplicationController.send :include, CorrelationId::ControllerExtension
lib/correlation_id.rb
require 'correlation_id/controller_extension'
module CorrelationId
end
Now, when I'm in the test/dummy
directory, which is a test rails app for my gem, I try to boot up the server using rails s
and I get the following error:
/correlation_id/lib/correlation_id/controller_extension.rb:17:in `<top (required)>': uninitialized constant ApplicationController (NameError)
I'm clearly having problems with referencing ApplicationController to monkey-patch it.
How would I manage this? I want my gem to be self-contained.
The following code works. What I did was prematurely create ApplicationController
with the appropriate inheritance. Note, many people use the rails-api
gem, so I factored in them to ensure the fact that it would work.
Also, note: You must inherit from a class because otherwise ApplicationController
will be a usual class that doesn't understand what after_filter
is.
module CorrelationId
module ControllerExtension
def self.included(klass)
klass.class_eval do
after_filter :pass_correlation_id
end
end
def pass_correlation_id
correlation_id = request.headers['Correlation-ID'] || SecureRandom.uuid
headers['Correlation-ID'] = correlation_id
end
def self.base_controller_inheritance
if Gem::Specification.find_all_by_name('rails-api').any?
ActionController::API
else
ActionController::Base
end
end
end
end
class ApplicationController < CorrelationId::ControllerExtension.base_controller_inheritance
include CorrelationId::ControllerExtension
end
I imagine there might be a better way to check if they are using ActionController::API
and if so, please do share, but as of now, this seems like the most solid way to do it.
这篇关于如何让我的宝石自成一体,无需编辑任何核心源代码Rails?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!