For the first time I have a question to an answer I already solved, this is more about WHY my little fix solved it in the first place.
I'm following the Learn Rails book tutorial by Daniel Kehoe, creating an application that is supposed to subscribe people to a MailChimp list. I'm using the Gibbon gem, and in the book this is (part of) the code in the model used to set the variables:
def subscribe
mailchimp = Gibbon::API.new(Rails.application.secrets.mailchimp_api_key)
result = mailchimp.lists.subscribe({
:id => Rails.application.secrets.mailchimp_list_id,
<more code here for email and stuff>
end
My secrets.yml file for the variables in question looks like this:
mailchimp_api_key: <%= ENV["MAILCHIMP_API_KEY"] %>
mailchimp_list_id: <%= ENV["MAILCHIMP_LIST_ID"] %>
And, since I'm on Windows, I set the actual value of them in application.yml: [Edit: As people have pointed out, this comes from the Figaro gem and may or may not be part of the tutorial]
MAILCHIMP_API_KEY: mysecretkey
MAILCHIMP_LIST_ID: mysecretid
This, I should note, works perfectly fine locally. I can run my server and subscribe. However, pushing it to Heroku and setting the ENV variables via heroku config:set MAILCHIMP_API_KEY=mysecretkey
and the same thing for MAILCHIMP_LIST_ID
, it doesn't work. More specifically, it returns the error Invalid Mailchimp List ID:
.
So, despite setting it and checking that it is actually set, it has no value at all for the List ID.
I fixed the problem by searching through Heroku's own help text on Config Vars, where it recommends the following: "Set up your code to read the vars at runtime. For example, in Ruby you access the environment variables using the ENV['KEY']
pattern"
I changed my code in the model, so instead of using Rails.application.secrets.mailchimp_list_id
it's now this:
def subscribe
mailchimp = Gibbon::API.new(Rails.application.secrets.mailchimp_api_key)
result = mailchimp.lists.subscribe({
:id => ENV['MAILCHIMP_LIST_ID'],
<more code here for email and stuff>
end
And, what do you know, it works in Heroku (and locally)! Why, though? I mean, it did understand the same kind of code for the API Key, but not for the list ID, which seems strange to me. Also, how come the book in question doesn't reflect on this? The author seems willing to update it very regularly, and I see him answer questions on it with an almost religious dedication. Am I the only one to run into this problem?
Edit: Solved below. I feel a bit silly now, and as usual things have a very easy solution. I will note that the book did in fact have the keys duplicated into production in the secrets.yml file, I just missed that part, probably because I had to find an alternative solution to the whole problem of environmental variables and using the Figaro gem. If I have any criticism of the book, it's that it doesn't cater to us poor Windows users. :)
Figaro creates the config/application.yml
file and according to its documentation, adds it to your .gitignore
:
This creates a commented config/application.yml file and adds it to your .gitignore. Add your own configuration to this file and you're done!
This is done to prevent sensitive secrets (like passwords and salts) from being committed into your Git repository, where those secrets would be compromised.
Figaro does have a feature which you can use to transfer all the settings in application.yml
to Heroku at once by running
figaro heroku:set -e production
As it turns out, the config/secrets.yml
did not repeat the Mailchimp keys in the production section. To fix this, it should look like this:
development:
mailchimp_api_key: <%= ENV["MAILCHIMP_API_KEY"] %>
mailchimp_list_id: <%= ENV["MAILCHIMP_LIST_ID"] %>
production:
mailchimp_api_key: <%= ENV["MAILCHIMP_API_KEY"] %>
mailchimp_list_id: <%= ENV["MAILCHIMP_LIST_ID"] %>