首页 > 解决方案 > Rails 5在gem railtie中有条件地需要一个依赖的gem及其初始化器

问题描述

我们正在为我们的几个共享应用程序编写一个包含多个常见 gem 的 gem。我们希望能够在消费应用程序中进行配置application.rb或类似的enviroment.rb/*rb东西config.fruit_chain.enable_transport = true,以有条件地需要一个 gem,并且它是动态的初始化器。但是来自普通 gem 的初始化程序不会在 railtie 中的 require 之后运行。我想知道是否有更好的方法来做到这一点

Fruit_store/config/application.rb 。(消费应用)

module FruitStore
  class Application < Rails::Application
    # Initialize configuration defaults for originally generated Rails version.
    config.load_defaults 5.2

    config.fruit_chain.enable_transport = true
  end
end

fruit_chain/lib/fruit_chain.rb(我们的宝石)

require analytic 
- require transport      <----- removed this so it dose not autoload
require marketing
...

module FruitChain
end

fruit_chain/lib/fruit_chain/rails/railtie.rb

module FruitChain
  module Rails
    class Railtie < ::Rails::Railtie
      config.fruit_chain = ActiveSupport::OrderedOptions.new
      config.fruit_chain.enable_transport = false

      config.before_initialize do |app|
        if app.config.fruit_chain.enable_transport
          Kernel.require 'transport'             <--- this require the gem correct and load it up         

          app.initializers.find{ 
            |a| a.name === 'transport.configure'
          }.run <--- transport.configure initializer doesn't kick off
        end        
      end
    end
  end
end

运输/lib/transport.rb 。(依赖普通宝石)

require transport/rails/railtie 
...

module Transport
end

运输/lib/transport/rails/railtie.rb

module Transport
  module Rails
    class Railtie < ::Rails::Railtie
      initializer 'transport.configure' do |app|
      ...
      end
    end
  end
end

标签: ruby-on-railsrubyrubygemsruby-on-rails-5gemspecs

解决方案


推荐阅读