Ruby on Rails:在开发中的初始化程序中配置API

时间:2015-07-20 10:55:36

标签: ruby-on-rails

我有一个带有lib API的Ruby on Rails应用程序。 lib中的文件是自动加载的,API是在初始化程序中配置的。

# lib/my_api.rb
module MyApi
  extend Configuration
end

# lib/my_api/configuration.rb
module MyApi
  module Configuration
    attr_accessor :my_setting
    def configure
      yield self
    end
  end
end

# config/initializers/my_api.rb
MyApi.configure do |config|
  config.my_setting = 'foo'
end

这适用于生产,但在开发过程中,API会在服务器启动时进行配置。更改某些代码后,配置会丢失,并且由于设置为nil而导致错误:

irb(main):001:0> MyApi.my_setting
=> "foo"
irb(main):002:0> reload!
Reloading...
=> true
irb(main):003:0> MyApi.my_setting
=> nil

我的猜测是,在开发过程中,会重新加载类,但初始化程序不会,这意味着它只能在启动服务器后配置一次。

现在我正在lib/my_api.rb复制我的配置,但这非常hacky。

这个问题的解决方案是什么?

2 个答案:

答案 0 :(得分:0)

module MyApi
  module Configuration
    mattr_accessor :my_setting
    def configure
      yield self
    end
  end
end

mattr_accessor是一个用于创建模块级访问器的ActiveSupport宏。

答案 1 :(得分:0)

好吧,在有人提出更好的解决方案之前,我已经提出了两个解决方法。我跟2去了。

  1. 不要自动加载lib目录(意味着不自动加载API)。这意味着必须在API代码更改时重新启动服务器,但解决了问题。这就是配置这样的宝石的原因 - 因为它们不是自动加载的。
  2. lib/my_api.rb

    结尾处手动重新加载开发中的初始值设定项

    load Rails.root.join('config/initializers/smart_meter.rb') if Rails.env.development?

  3. 当Rails自动加载类时,MyApi常量将被新的常量替换。配置仍可在旧对象上使用:

    Loading development environment (Rails 4.2.0)
    irb: warn: can't alias context from irb_context.
    irb(main):001:0> MyApi.my_setting
    => "foo"
    irb(main):002:0> OldMyApi = MyApi
    => MyApi
    irb(main):003:0> reload!
    Reloading...
    => true
    irb(main):004:0> MyApi.my_setting
    => nil
    irb(main):005:0> OldMyApi.my_setting
    => "foo"
    irb(main):006:0> load Rails.root.join('config/initializers/smart_meter.rb')
    => true
    irb(main):007:0> MyApi.my_setting
    => "foo"