How can duplication be removed from this?
class Authentication PROVIDERS = if Rails.env.production? %w(weibo open_wechat wechat) else %w(weibo open_wechat wechat developer) end.freeze end
Rails already has environment-specific configuration via the files in
config/environments. As explained in the Rails Guides, you can simply do
# in config/application.rb (the default config) config.authentication_providers = %w(weibo open_wechat wechat)
# in config/environments/development.rb (overrides the default) config.authentication_providers = %w(weibo open_wechat wechat developer)
Edit: Or, as 200_success points out in the comments, you can simply add
"developer" to the existing list:
# add another item to the default config instead of redefining it completely config.authentication_providers += %w(developer)
config.authentication_providers << "developer"
Note that the strictest configuration is used as the default - the less strict one you have to explicitly set for a given environment (such as
You code then becomes:
class Authentication PROVIDERS = Rails.configuration.authentication_providers end
Or you can simply skip the constant, since there's no need for it anymore; the list isn't being defined in class at all.
But another, and often times better, way to handle stuff like this is to use environment (ENV) variables, as explained in chapter 3 of "The 12 Factor App" (read it). You'll set the variables one way for
production, another way for
development, yet another for
test perhaps, and so on if you have more environments.
Another great explanation, although it's now subscription-only*, is this Railscast episode. While the episode isn't brand-new anymore, the advice in it is absolutely still valid.
Anyway, one major point is that ENV configuration do not need to be included in source control, which is great if the configuration contains sensitive things like API keys or passwords. Rails already hits upon this point for the
secret_key_base variable, where, in
config/secrets.yml, it says simply:
# Do not keep production secrets in the repository, # instead read values from the environment. production: secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
Again, there are many way to handle it. The basic premise is that stuff that changes from environment to environment should be accessed through the ENV. That's what it's for, after all. Again, read this.
*) Well worth the $9! Since Railscasts on indefinite - possibly permanent at this point - hiatus, you'll only be charged $9 for the first month, but there won't be a monthly charge (unless Ryan decides to start back up again). See this announcement for details.