I declare in advance the length of this post ....
I am developing a rais application that uses a clip to store things on Amazon S3. The application is hosted on Heroku. I am developing on Ubuntu Karmic.
The problem I'm going to describe arises in development (on my localhost) and production (on Heroku).
The standard way to pass S3-Creds to paperclip is to put them in config / s3.yml as follows:
access_key_id: 12345678 secret_access_key: 903490409fdf09fshsfdoif/43432
When I do this, everything works fine. But this makes it difficult to share my code with others, so Heroku offers an alternative method - http://docs.heroku.com/config-vars .
They advise you to put your S3_KEY and S3_SECRET in your .bashrc like this:
S3_KEY=12345678 export S3_KEY S3_SECRET=903490409fdf09fshsfdoif/43432 export S3_SECRET
Then they suggest creating config / initializers / s3.yml (note a slightly different path) and put the following into this file:
AWS::S3::Base.establish_connection!( :access_key_id => ENV['S3_KEY'], :secret_access_key => ENV['S3_SECRET'] )
BUT. When I do this, paperclip throws out the wobbler and spits out the following error message:
undefined method `stringify_keys' for #<String:0xb6d6c3f4> /vendor/plugins/paperclip/lib/paperclip/storage.rb:176:in `parse_credentials' /vendor/plugins/paperclip/lib/paperclip/storage.rb:138:in `extended' /vendor/plugins/paperclip/lib/paperclip/storage.rb:137:in `instance_eval' /vendor/plugins/paperclip/lib/paperclip/storage.rb:137:in `extended' .... other stuff
So itβs clear that all this happens in the storage.rb module. Running a stack trace:
The parse_credentials parameter on line 176 is marked - here's the call, as it appears in the code:
def parse_credentials creds creds = find_credentials(creds).stringify_keys (creds[RAILS_ENV] || creds).symbolize_keys end
The parse_credentials method tries to call another find_credentials method, and it is here that I believe that the problem lies. Here is the code for find_credentials:
def find_credentials creds case creds when File YAML::load(ERB.new(File.read(creds.path)).result) when String YAML::load(ERB.new(File.read(creds)).result) when Hash creds else raise ArgumentError, "Credentials are not a path, file, or hash." end end
I do not see how the find_credentials method is equipped to read values ββfrom my .bashrc file. He got two cases where he can read from YAML and one where he is looking for a hash.
My model refers to these credentials:
has_attached_file :photo, (some code removed) :s3_credentials => "#{RAILS_ROOT}/config/initializers/s3.yml",
If I remove the hash code: s3_credentials from the model, the stringify_keys error disappears and the rails console gives an error message that appears at the end of the find_credentials method: ie "Credentials are not a track, file or hash" ,.
So I'm at a dead end. I understand that this may be a question for the guys at Heroku (who am I really going to email this link in the hope that they will be able to answer it), and this may also be a question for doods when thinking, but I I thought that StackOverflow might be the best place to ask about this, as it turned out to be a pretty reliable forum for me in the past.
As I said at the beginning, my application works fine when I take the standard approach of inserting my key and secret in config / s3.yml, but I would prefer to use the method that Heroku offers, because it makes things easier for me, and this means that I can save my repo on my public github page for use by others without writing any client merge drivers to Git so that my api keys exit the public domain.
Once again, sorry for the long post, and if you have made it this far, I welcome you. Does anyone have any idea?
I tried sticking to ENV variables in etc / bash.bashrc as well as ~ / .bashrc and after rebooting I still have the same problem. Problems arise on development machines, as well as on Heroku. I made sure to push my config vars to Heroku.
I have been on it for 8 hours in a row! I'm going to watch football now.