在Rails.application.secrets中使用OrderedOptions

时间:2014-10-02 15:59:57

标签: ruby-on-rails-4

我一直致力于使用Rails 4.1.1的新代码库。我有一个secrets.yml文件,其格式类似于:

development:
  secret_key_base: 12345

  foo: &development_foo
    application_id: 2345
    username: foobar
    password: Password123

test:
  ...
  foo:
    <<: *development_foo

Rails.application.secrets是类OrderedOptions的对象。对于OrderedOptions According to the documentation,该类的存在只是为了允许您访问键/值对中的值,如下所示:Rails.applications.secrets.secret_key_base。这样,我可以使用点表示法访问开发组内的所有顶级键。

但是,当您尝试使用相同的点表示法(appication_id)访问Rails.application.secrets.foo.application_id时,会出现undefined method 'application_id' for #<Hash>错误。这是因为foo不是OrderedOptions的实例,而只是普通的Hash

仅制作OrderedOptions的顶级键实例的理由是什么?为什么不制作所有键OrderedOptions,以便您可以使用点符号表示所有内容?我可以理解,如果你在secrets.yml内有一个深层嵌套的值,使用点符号会变得很难看,但我很好奇为什么可能做出这个决定。

1 个答案:

答案 0 :(得分:0)

来自Rails的有趣位代码

来自 ActiveSupport :: OrderedOptions&lt;

散列

def method_missing(name, *args)
  name_string = name.to_s
  if name_string.chomp!('=')
    self[name_string] = args.first
  else
    self[name]
  end
end

来自 Rails :: Application

def secrets #:nodoc:
  @secrets ||= begin
    secrets = ActiveSupport::OrderedOptions.new
    yaml = config.paths["config/secrets"].first
    if File.exist?(yaml)
      require "erb"
      all_secrets = YAML.load(ERB.new(IO.read(yaml)).result) || {}
      env_secrets = all_secrets[Rails.env]
      secrets.merge!(env_secrets.symbolize_keys) if env_secrets
    end

    # Fallback to config.secret_key_base if secrets.secret_key_base isn't set
    secrets.secret_key_base ||= config.secret_key_base
    # Fallback to config.secret_token if secrets.secret_token isn't set
    secrets.secret_token ||= config.secret_token

    secrets
  end
end

正如您所看到的,Rails.application.secretsActiveSupport::OrderedOptions的一个实例。 OrderedOptions是一个简单的哈希,使用method_missing方法来查找键值,因为它们是方法。

因此,在您的secrets.yml for env密钥中,有secret_key_basefoo,因此您可以将它们(仅限它们)用作方法调用。