Adding urls api keys in environment variable in ruby - ruby-on-rails

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]

Related

Some environmental variables accessible, others not?

I have a rails app and am trying to use an environmental variable (API key) inside of a controller and it is failing. Debugging shows it's value to be nil. Weird thing is that other keys from that file are accessible, so I am not really understanding why. They are all in my secrets.yml file.
I have tried accessing it using both ENV["STRIPE_TEST_SECRET_KEY"] and Rails.application.secrets.stripe_test_secret_key and both come back nil. I get the error:
No API key provided. Set your API key using "Stripe.api_key = <API-KEY>". You can generate API keys from the Stripe web interface. See https://stripe.com/api for details, or email support#stripe.com if you have any questions.
using the better errors gem. How do I make these available throughout my app?
You need to set STRIPE_TEST_SECRET_KEY in the environment running the Rails app.
Check out the Choices gem, it makes overriding env vars pretty easy.
You can set the env vars on the CLI in development like this:
$ STRIPE_TEST_SECRET_KEY=abc123 rails s
If you are using Rbenv, you can create a .rbenv-vars file in the root of your project that contains one env var per line like this:
DATABASE_URL=mysql://db_user:db_pass#localhost:3306/dev_db
STRIPE_TEST_SECRET_KEY=abc123
SOME_OTHER_VAR=foo

Setting Test environment variables in rails without putting in source code

I'm using Twilio for an app and on production I set the auth token using heroku's CLI. I'm using sms-spec (https://github.com/monfresh/sms-spec) to test my app's Twilio integration locally. I want to set ENV['TWILIO_AUTH_TOKEN'] to my token in the test environment.
I use guard to auto-run my tests whenever I make changes so I don't want to have to manually set the ENV variable each time I run tests. I also don't want to put the token in my source code for security reasons.
Is there a way I can set the ENV variable for my local test environment such that it is permanent and not in my source? I've spent a few hours researching this and can't seem to find a good explanation of how to do this. Any help is much appreciated :)
Two approaches:
Use a gem like Dotenv (link). This is the approach I use in most of my applications for development. Simply include the gem in your gemfile, bundle install and then store any environment variable settings in a top level file called .env. Restart your rails server and ENV will be automatically loaded. Very easy to use and convenient.
If you are flexible on the ENV part, and you are running Rails 4.1+, you can use config/secrets/yml. This is documented very well in the Rails 4.1 release notes, Section 2.2. So, in your case, you would set it up like so:
development:
twilio_auth_token: verysecretstring
Then, in your initializer, instead of referencing ENV['TWILIO_AUTH_TOKEN'], you would use Rails.application.secrets.twilio_auth_token. I haven't tried this myself, but it is on my list as I would rather use native Rails functionality than a separate gem.
Of course, any files which contain your secrets needs to be safeguarded carefully. At a minimum, make sure you include in .gitignore so that your secrets do not find their way into your code respository.

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.

Assigning Environment Variables in Ruby on Rails

I have a program that makes calls to an internal web API. However when we're doing development work on the sites we don't want the program to call our production web API but the staging version of the Web API. What's the best way to do this in rails?
I feel I should be assigning some sort of variable in development.rb and one in production.rb
Thanks
Yes, just add a variable to development.rb and production.rb like:
OUR_API_URL = "http://somepath"
Then you can use OUR_API_URL in your code.

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