如何让我的宝石自足,而无需编辑任何芯源Rails的?(How to keep my gem self

2019-10-29 02:06发布

我想添加一个过滤器到ApplicationController ,但我想我的宝石之内做到这一点。

我想避免如下:

class ApplicationController < ActionController::Base
  include MyGem
end

我不要那个。 我不希望有包括我的源代码模块。

我虽然有问题。

下面是相关的代码:

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

现在,当我在我test/dummy目录,这是对我的宝石测试Rails应用程序,我尝试使用来启动服务器rails s ,我得到以下错误:

/correlation_id/lib/correlation_id/controller_extension.rb:17:in `<top (required)>': uninitialized constant ApplicationController (NameError)

我清楚地具有参考的ApplicationController猴子补丁它的问题。

我将如何管理呢? 我希望我的宝石是自包含的。

Answer 1:

下面的代码工作。 我所做的就是过早地创建ApplicationController使用适当的遗产。 注意,很多人使用rails-api宝石,所以我在他们分解,以确保事实,即它会正常工作。

此外,请注意:必须从一个类继承,因为否则ApplicationController将是一个常用的类不明白什么after_filter是。

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

我想有可能是一个更好的方法来检查,如果他们使用ActionController::API如果是的话,请做份额,但截至目前,这似乎是最可靠的方法来做到这一点。



文章来源: How to keep my gem self-contained without having to edit any core source Rails?