过去几天,我一直在努力解决我正在开发的Ruby on Rails应用程序中遇到的问题。我有不同的国家/地区,我们使用不同的Amazon S3存储桶。 Amazon S3密钥凭证在config / environments / environment_name.rb中存储为常量(例如:demo.rb)我无法确定从配置文件操作的国家/地区。我可以从控制器,模型,视图等确定我们正在操作的国家/地区,但不能从配置文件中确定。是否有Ruby元编程或其他一些我不知道的魔术,所以我想说如果我们在应用程序中作为一个国家在英国工作,使用英国的桶凭据或德国作为国家,请使用德国的桶凭证?我想不出从app本身传递参数到环境文件的方法。非常感谢您提供的所有帮助。
答案 0 :(得分:0)
您可能应该为每个请求选择相关的凭据,而不是将配置详细信息实际传递给您在启动时使用的S3客户端。您的配置文件可以将它们全部定义为哈希,如下所示:
# config/s3.rb
S3_BUCKETS => {
:us => 'our-files-us',
:gb => 'our-files-gb',
:tz => 'special-case'
}
然后您可以根据请求选择凭据(可能是您的AppController):
bucket_name = S3_BUCKETS[I18n.locale]
# pass this info to your S3 client
有意义吗?
答案 1 :(得分:0)
如果您想要了解主要应用程序中的每个国家/地区配置,请编写一个小型中间件。
中间件非常简单。无所事事的中间件看起来像这样:
class DoesNothing
def initialize(app, *args)
@app = app
end
def call(env)
@app.call(env)
end
end
Rack通过将一系列中间件链接在一起来为应用程序提供动力......每个中间件都被引用@app,这是链中的下一个链接,它必须在该应用程序上调用#call
。链末尾的那个运行应用程序。
所以在你的情况下,你可以在这里做一些额外的配置。
class PerCountryConfiguration
def initialize(app)
@app = app
end
def call(env)
case env["COUNTRY"]
when "AU"
Rails.application.config.s3_buckets = { ... }
when "US"
Rails.application.config.s3_buckets = { ... }
... etc
end
@app.call(env)
end
end
有几种方法可以使用中间件,但由于它依赖于对Rails环境的访问,因此您需要从Rails内部进行操作。把它放在你的application.rb中:
config.middleware.use PerCountryConfiguration
如果要将其他参数传递给中间件的构造函数,只需在类名后面列出:
config.middleware.use PerCountryConfiguration, :some_argument
您还可以从ApplicationController内部安装中间件,这意味着所有初始化程序和所有内容都已经执行,因此它可能在链中太远。