0

我一直在努力应对目前正在研究的Ruby on Rails应用程序中过去几天的问题。我有不同的国家,每个国家我们都使用不同的Amazon S3存储桶。 Amazon S3密钥凭证存储为config/environments/environment_name.rb中的常量(例如:demo.rb)我无法从配置文件中确定我们正在运行哪个国家/地区。我可以从控制器,模型,视图等中确定我们正在操作哪个国家,但不能从配置文件中确定。有没有Ruby meta编程或其他一些我不知道的魔法,所以我想说如果我们在应用程序中使用英国作为国家,使用英国的存储凭据或德国作为国家,使用德国的存储桶凭据?我想不出从应用程序本身传递参数给环境文件的方法。非常感谢您的帮助。将变量从Rails应用程序传递到config/environments/demo.rb

+0

你有没有在控制器中如何做的例子?这是一个GeoIP的东西,还是你手动设置一些标志? – d11wtq

+0

我问的原因是,我认为你要找的是一个中间件,它会在rails执行之前根据请求设置一些额外的配置。 – d11wtq

+0

这不是一个geoip的东西,我将所有东西都设置为环境文件中的常量,并在控制器中使用这些凭据。 –

回答

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 

有意义吗?

+0

非常感谢。我会试一试。 –

+0

非常好,非常感谢。只是一个简单的问题:比方说,我有一个类方法,我想在它们上使用关联。什么是简单的方法来做到这一点? –

+0

@SaitIlhaner:什么? – coreyward

0

编写一个小中间件,如果你想保持每个国家的配置知识的主应用程序。

中间件非常简单。一个什么都不做中间件是这样的:

class DoesNothing 
    def initialize(app, *args) 
    @app = app 
    end 

    def call(env) 
    @app.call(env) 
    end 
end 

机架功率应用程序通过链接一系列中间件一起......每一个都有一个参考@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的内部,这意味着所有的初始化器和所有的东西都已经被执行,所以它可能在链中太过分了。

+0

非常感谢。这真的很有帮助。除了当我使用OmniAuth和Devise之前,我从来没有对中间件堆栈做过任何事情。我从来没有写过自己的中间件。 –

+0

我想大多数人都没有意识到中间件只是一种方法:) – d11wtq