1

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. :)

2 Answers2

1

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"] %>
fivedigit
  • 18,464
  • 6
  • 54
  • 58
  • Ah, yes. I forgot if Figaro was part of the tutorial or not... I remember having a great deal of trouble with the ENV variables, using Windows as I am. However, how does this explain my problem exactly? Why does my application work locally and not on Heroku with the old code? –  Dec 23 '14 at 07:55
  • I've highlighted the exact why in a new paragraph. Since it is ignored by Git, it won't be pushed to any remote, including Heroku. – fivedigit Dec 23 '14 at 07:57
  • No, I get that. It's no different from using a bashrc file or whatever it's called, which also doesn't get pushed to Heroku. I set the variables via heroku config:set, so it shouldn't matter. It DOES get my API Key, but not the List ID, after all. Edit: In fact, it gets all my variables, it just doesn't understand that I wish to access it with the old code syntax. –  Dec 23 '14 at 07:59
  • Ah now I see what you meant. It *should* be working with the old as you posted it, I cannot find any issues there. Did you try changing it back to the old code to see if it works now on Heroku? – fivedigit Dec 23 '14 at 08:05
  • Tried it now. Same error: `Gibbon::MailChimpError (Invalid MailChimp List ID: )`. I'm glad someone else is also confused by this! –  Dec 23 '14 at 08:11
  • Did you try running the Rails console on Heroku (`heroku run rails c --app yourapp`) to check what the exact value of `Rails.application.secrets.mailchimp_list_id` is? – fivedigit Dec 23 '14 at 08:15
  • Didn't know about that. It returns `nil` as expected. Edit: So does `Rails.application.secrets.mailchimp_api_key` by the way. But yet it gets its value somehow... –  Dec 23 '14 at 08:17
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/67520/discussion-between-fivedigit-and-lyndon-johnson). – fivedigit Dec 23 '14 at 08:17
0

Had almost the exact same error, but a slightly different cause.

Double check to make sure your secrets.yml is properly configured. Mine looked like the following:

...
production:
  mailchimp_api_key: <%= ENV["MAILCHIMP_API_KEY"] %>
  mailchimp_list_id: ENV["MAILCHIMP_LIST_ID"]
...

I didn't see the missing <%= %> after scanning the file MANY times, even after I ended up on this page. I'll leave this answer up in case Google sends others with the same typo here.

Tristan Tao
  • 855
  • 11
  • 29