4
votes

We have already built a rails app that has several users and an image for each of them. Doing all of the dev work on our localhost, we have working seeds for users & photos...but now that we are trying to use S3 for the image storage, we are running into errors during...always during the "seed" step of the migrations, when doing this:

rake db:migrate:reset

Apologies for the question, but we have have been banging our heads on this for 11 hours, having gone through every related Stack question on the subject. A lot of similar posts had a NoSuchBucket error and other types of issues, but we none of the suggested changes have fixed our issue...maybe it's related to the newest versions of the gems we are using?

We are using Rails 3.0.4, Ruby 1.8.7, Paperclip 2.3.8, aws-s3 0.6.2

We are adding seeds for initial users and a photo for each user using our seeds.rb file in the /migrate/ folder. This always worked fine when storing files and images on local machine (using paperclip, but not S3). We also have tested removing the seeds file and simply creating a new user with the working app and got the same error:

Credentials are not a path, file, or hash

For the user module, we have tested both the option where we set the following S3 keys through both the (a) yml file and (b) directly in the user model. access_key_id: 'secret' secret_access_key: 'secret'

We have tried doing this from our localhost (not yet live on heroku), and we have also tried running this through Heroku.

We have tried seemingly every permutation of the layout of those keys, but the error we most frequently get is this:

can't convert Module into Hash

Googling this error message returns zero results, so we don't know what's happening there. This was the most frustrating part...seemingly every attempt got us back to this error.

We also tried both:

(1) hardcoding the access keys in the user model, both like this:

:access_key_id => ENV['accesskeyid'],
:secret_access_key => ENV['secretaccesskey'],

In this case, we often got this error:

You did not provide both required access keys. Please provide the access_key_id and the secret_access_key.

Frustrating, because we always had both items listed, tested with and without quotes, changing up the order, etc.

We tried it both (a) with the ENV['accesskeyid'] and (b) without those...with simply blahblah => 'accesskeyid'.

and (2) putting the keys into the yml file, like this:

has_attached_file :photo,
  :storage => :s3,
  :s3_credentials => "#{Rails.root}/config/s3.yml",
  :path => "/:photo/:filename"

with this in the yml file:

development:
  access_key_id: accesskeyid
  secret_access_key: secretaccesskey
  bucket: ourbucketname
production:
  access_key_id: accesskeyid
  secret_access_key: secretaccesskey
  bucket: ourbucketname

We tried this with single quotes around the keys, and without.

We also tried defining the bucket in the model, rather than in the yml file, and got the same error.

and (3), setting it up this way:

if Rails.env == "production" S3_CREDENTIALS = { :access_key_id => ENV['S3_KEY'], :secret_access_key => ENV['S3_SECRET'], :bucket => "ourbucket"} else S3_CREDENTIALS = Rails.root.join("config/s3.yml")
end

has_attached_file :photo, :storage => :s3, :styles => { :small => "50x50>", :thumb => "75x75>", :medium => "400x400>"}, :path => "/:photo/:filename"

With the same contents in our yml file.

This gave us this error:

credentials are not a file, path, or hash

Naturally, we quadruple-checked that we had the correct access keys (from our AWS account) and tested several different ways of setting up the hash, but never got what we wanted.

Here is the relevant portion of Gemfile: gem 'aws-s3', :require => 'aws/s3' #For Storing Images on Amazon gem 'paperclip'

As another attempt, we tried to use the gem right_aws, instead, in the Gemfile, but this resulted in this error:

no such file to load -- aws/s3 (You may need to install the aws-s3 gem)

Note, we have been doing all of this and hitting all of these errors doing migrations from from localhost, not from the live Heroku app, but couldn't even get past this simple 'seed users' step.

Currently, our bucket is titled media.oururl.com. Is there some issue with having periods in the bucket name?

Going to ask the heroku guys about this, as well, but considering how amazing this community is, I am hoping one of you knows what we're doing wrong her.

MUCH appreciated - and hopefully this helps others who follow behind us.

1

1 Answers

5
votes

excellent question. I spent quite some time with a similar issue a while ago

The primary issue is that you need to move the following code into it's own initializer file:

if Rails.env == "production" 
   S3_CREDENTIALS = { :access_key_id => ENV['S3_KEY'], :secret_access_key => ENV['S3_SECRET'], :bucket => "ourbucket"} 
 else 
   S3_CREDENTIALS = Rails.root.join("config/s3.yml")
end

Then, you should add the following line to your model where you have *has_attached_file :photo* The line to add is.

:s3_credentials => S3_CREDENTIALS,

This is what you were missing before.

Also, for when you declare your bucket name, make sure that is for standard us. If you use one of the other locations, you'll have to update the path appropriately.

Hope this helps!