What is the best way to manage configurations in Ruby on Rails? - ruby-on-rails

I have an app that has a lot of api keys and setting to be managed and they are loaded using an initializer. BEcause they are different for each environment, I can't set a constant in the environment.rb file. (I tried that; didn't work.) So I started comment-and-uncomment by hand before every deployment, which is tedious. I'm wondering what would be a best practice for a situation where you have to deal with multiple configuration settings loaded in an initializer.

In your environment.rb you can set your keys if the request is coming from local:
Rails::Initializer.run do |config|
if local_request?
CONSTANT1 = 10
else
CONSTANT1 = 20
end
end
What this will do is check if you are on localhost which is localhost:3000, your development environment. If so then the if/else statement will pick which constant to set.
another option would be to set the constants in your environments folder which is probably a better idea
so for your production constants put them in config/environments/production.rb.
and for your development constants put them in config/environments/development.rb.

You should be setting these constants in initializer files, which you can create under the initializer directory. Then, use the environment-specific config files that are under the environments directory to set them per environment.

Related

Best way to set environment-specific variables in rails

There are certain variables I would like to have in the development environment, and certain variables for the production environment. For example, in production mode, I might want to use a cache to speed up performance. I have couple of open-ended questions about this:
Question: What is the easiest and fastest way to set environment variables in a rails app? For example, ENV["USE_CACHE"] = true in production, and = false in development.
If you could point to a specific gem, and/or the specific files I'd need to touch, that would be most helpful. Thanks!
I learnt few things about ENV variables this discussion
You can set ENV varaibles by just appending
export USE_CACHE=true
to your .bashrc file.
...and in your application you can use
ENV["USE_CACHE"]
,
you can also check out figaro and dotenv which are application specific.
For your purpose just use
if Rails.env.eql?("development")
#do stuff
end
Its upto you choose easiest and fastest way!

Use Ruby on Rails environment config based on URL/Machine Name

I have a RoR3 app with multiple environment configs, development.rb, test.rb and production.rb.
Is there a way I can instruct the application to used a specific config based on a value in the URL or machine name??
For instance if the machine name contains "dev", then use development.rb.
Edit
If that is not possible, is there a way I can access the request URL from the application.rb or environment.rb files maybe. If so, I could probably use a regex on the URL to determine and set the environment settings dynamically within if blocks.
In the end, we'll end up having many more than just 3 environments, all with certain differences. So I need a very flexible way to set the config.
Probably not. By the time the rails app is running (and can look at the machine name) it's already picked an environment. Unless you hack the boot script...
It'd be much easier to just put the environment into the startup-command-line for each machine.

Adding urls api keys in environment variable in ruby

I have a url that I am using in one of the controllers. Is there a better place to put this url? The url uses an API key and I was wondering if there is a better place to add this url and/or api key such that its not added in the controller class code and ergo more editable? If i add it as an environment variable or anything else how do i access it from my controller class? thank you. ITS A RUBY AND RAILS PROJECT
Using environment variables might be a good idea if you want to keep things like API keys and passwords out of your source code. Accessing them from within your code is done with the ENV object:
my_api_key = ENV['MY_API_KEY']
To use this technique, you need to set up the variables in your environment before launching your app, and how you do this depends on your local setup, and will likely also vary between development and production.
In development, you can simply set the environment vars in your shell, e.g. with bash:
$ export MY_API_KEY=foobar123abc
$ rails s
Now rails will start and have access to this environment variable. You can also set variables for just a single command:
$ MY_API_KEY=foobar123abc rails s
Depending on what the sevice/api is, you could set some of them to default development/test values in config/environments/development.rb (or test.rb):
ENV['MY_API_KEY'] = 'non_secret_api_key_that_can_be_shared_around'
Setting up environment variables in production will depend on how you're deploying your app. Phusion have an article on using environment variables in Passenger if your using that. There's also a useful article on using environment variables with Heroku which is worth a read even if you're not using them for deployment.
You can add it to application.rb file as
config.service {
:api_key => 'api_key'
}
Or better yet, add it to development.rb and production.rb files so that you can test it better.
You can access this api_key from controller like
Rails.application.config.service[:api_key]

Is environment.rb invoked on every http request?

I'm wondering what file I should use to ensure my initializing code will only be executed once when the application starts up. Is environment.rb the correct file to use or will it be invoked on every http request?
environment.rb is only loaded when the application is first started up. subsequent changes to the environment.rb file require a restart. What kind of code do you only want to execute once?
You might want to read through the Ruby on Rails guide for Configuring Rails Applications which talks about the different places to put initialization code.
Look at config/initializers for the recommended location custom startup code.
As far as possible leave environment.rb alone unless you're explicitly adding or changing items defined within the Rails::Initializer.run block.
If you want to manage custom settings across your various environments, e.g. you want production and development to have different settings for something, then the config/environments directory should be your first port of call.

How to use a Rails environment variable in Capistrano deploy script?

If I have a constant in my Rails environment.rb, for example...
SOME_CONSTANT = 3
Is it possible to access this in my capistrano deploy.rb somehow? It seems simple but I can't figure out how.
This ended up working:
created a file config/initializers/my_constant.rb
put my constant in there (rails automatically loads files there so I can use the constant in my app)
then in deploy.rb added load 'config/initializers/my_constant' so it could be used there as well.
You should access it via the ENV[] hash (this is a Ruby thing), here is an example using the TERM environmental variable.
puts "Your Terminal is #{ENV['TERM']}"
If you need a ruby constant, from your rails environment, you should load it:
require 'config/environment'
Beware that this will load your whole application environment, you should think to use something like AppConfig, or SimpleConfig (insert other tool here) to store configurations, then you need only load the tool, which processes your config files.
Why not define these constants in a file in lib/ and then require the file in both your Rails app and your Capfile?
As the value is not only used by the rails app, I would probably store such configuration information in a language agnostic format (yaml, json, ini, xml) which can be easily parsed by different tools without fear of possible side effects.

Resources