Search code examples
ruby-on-railsherokuamazon-s3paperclipgrape-api

Upload image to S3 through Heroku by paperclip


I'd like to upload image from iOS to S3 through Heroku by paperclip. I've used this website as reference. https://devcenter.heroku.com/articles/paperclip-s3

However, it return the error "status code: 500, headers". I'm not sure what is the problem. I'm looking forward to hearing from you.

#terminal
$heroku config:set S3_BUCKET_NAME="kenja.jp"
$heroku config:set AWS_ACCESS_KEY_ID=my_access_key_id
$heroku config:set AWS_SECRET_ACCESS_KEY=my_secret_access_key

#app/models/user.rb
has_attached_file :photo, 
  :styles => { medium: "300x300>", thumb: "100x100>" },
  :storage => :s3,
  :bucket => 'kenja.jp',
  :s3_permissions => :public,
  :url => ":s3_domain_url",
  :path => "/assets/photos/:id/:style/:basename.:extension",
  :s3_host_name => "s3-ap-northeast-1.amazonaws.com",
  :s3_credentials => :"#{Rails.root}/config/s3.yml"


#config/environments/staging.rb
config.paperclip_defaults = {
  :storage => :s3,
  :s3_credentials => {
    :bucket => ENV['kenja.jp'],
    :access_key_id => ENV['my_access_key_id'],
    :secret_access_key => ENV['my_secret_access_key']
  }
}


#config/paperclip.rb
Paperclip::Attachment.default_options[:url] = ':s3_domain_url'
Paperclip::Attachment.default_options[:path] ='/:class/:attachment/:id/:style.:extenstion'
Paperclip::Attachment.default_options[:s3_host_name] = 's3-ap-northeast-1.amazonaws.com'


#app/apis/v1/users.rb
  params do  
    requires :id, type:Integer
    requires :icon, type:Rack::Multipart::UploadedFile
  end
  post '/post_picture' do
    photo_file = ActionDispatch::Http::UploadedFile.new(params[:icon])
    @user = User.find(params[:id])
    @user.update(photo: photo_file)
    @user.photo
  end

Logs

I've checked heroku logs, then it said the following.

2015-10-18T06:33:10.144859+00:00 app[web.1]:  app/apis/v1/users.rb:112:in `block (2 levels) in <class:Users>'
2015-10-18T06:33:10.144858+00:00 app[web.1]: NameError (uninitialized constant Paperclip::Storage::S3::AWS):
2015-10-18T06:33:10.128265+00:00 app[web.1]:  User Load (0.9ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1  [["id", 15]]

This link told me that I need to downgrade the version of aws-sdk. NameError (uninitialized constant Paperclip::Storage::S3::AWS):

gem 'aws-sdk', '< 2.0'

Solution

  • Here's your error:

    NameError (uninitialized constant Paperclip::Storage::S3::AWS)

    After looking online, this is basically caused by the aws-sdk v2 gem not having the AWS module defined. In short, this means that Paperclip is unable to call the module required to save its data to S3.

    The workaround is to downgrade your aws-sdk version to 1:

    #Gemfile
    gem 'aws-sdk', '< 2.0'
    

    ... however, who likes workarounds?

    You should be able to get it working if you pull from the Paperclip master branch:

    #Gemfile
    gem "paperclip", git: "https://github.com/thoughtbot/paperclip.git", branch: "master"