我一直致力于使用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
内有一个深层嵌套的值,使用点符号会变得很难看,但我很好奇为什么可能做出这个决定。
答案 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.secrets
是ActiveSupport::OrderedOptions
的一个实例。
OrderedOptions是一个简单的哈希,使用method_missing方法来查找键值,因为它们是方法。
因此,在您的secrets.yml
for env密钥中,有secret_key_base
和foo
,因此您可以将它们(仅限它们)用作方法调用。