Last Updated: April 20, 2021
·
14.29K
· rorykoehler

Set up Ruby on Rails with Paperclip 5 and S3 using AWS SDK v2

Before you get started please ensure you have Imagemagick installed on your machine. This is a necessary component for the tutorial. To do this please follow the instructions under the Image Processor section here.

In preparation for the release of Rails 5, Paperclip devs have updated the gem to version 5. This now works with version 2 of the 'aws-sdk' gem. Previously with Paperclip 4 we needed to specify gem 'aws-sdk' '< 2.0' in our gem file but now we can go with gem 'aws-sdk', '>= 2.0.34' (as per the Paperclip docs) or simply gem 'aws-sdk' for the latest version.

At the same time you can install Paperclip 5 by putting gem 'paperclip' in your gemfile. With the two new gemfile entries present run bundle install.

Once the gems are installed it's time to setup your paperclip config. You can do this in config/application.rb or in config/environment/<your environment>.rb (i.e. config/environment/development.rb for the development environment). The code for global config should look like this:

#paperclip S3 
config.paperclip_defaults = {
    storage: :s3,
    s3_region: ENV["AWS_S3_REGION"],
    s3_credentials: {
      s3_host_name: ENV["AWS_S3_HOST_NAME"],
      bucket: ENV["AWS_S3_BUCKET"],
      access_key_id: ENV["AWS_ACCESS_KEY_ID"],
      secret_access_key: ENV["AWS_SECRET_ACCESS_KEY"]
      }
    } 

For those coming from Paperclip 4 and AWS SDK v1 please note that S3_region is now a (new) necessary param

I'm using the gem envyable to set my environment variables. It has easy to follow setup doumentation on the linked github page. Paperclip 5 / S3 won't work yet because we still need to attach an image to a model. Generating a model for the first time you could do something like this:

rails g model Image image:attachment

You will probably want to include other fields too but this will set you up to upload an image to the database. If you already have a model and want to add a image to it you will have to run a migration to add an attachment field type to the existing model. After running this command and then also rake db:migrate to migrate it to the database, the next step will be to add the necessary information to the Image model file (found at app/models/image.rb). Your file should look something like this (feel free to change the sizes of the images etc):

class Image < ActiveRecord::Base
  has_attached_file :image, :styles => { :medium =>     "300x300#", :thumb => "200x200#" }
  validates_attachment :image, content_type: { content_type:     ["image/jpg", "image/jpeg", "image/png"] }
end

Finally the last piece of the puzzle is to create the S3 bucket on the AWS Console. After this create a IAM user credentials in the AWS dashboard and give it full S3 usage rights (the amazon documentation is straight forward and will guide you through doing this). Save the IAM security credentials to in ENV["AWS_ACCESS_KEY_ID"] & ENV["AWS_SECRET_ACCESS_KEY"] respectively, the bucket name in ENV["AWS_S3_BUCKET"], your selected region host name in ENV["AWS_S3_HOST_NAME"] and finally your region in ENV["AWS_S3_REGION"]. You can find the correct region and host name informantion here.

Now restart your rails app server and you should be good to go. Further information on how to setup forms etc is available in the paperclip documentation linked at the top of the post or in your respective gem documentation (e.g. ActiveAdmin, Formtastic etc). Essentially a filefield with :image param attached will upload your image to S3. To add an image to a view call @image = Image.find(params[:id]) in the controller and then `imagetag(@image.image.url(:thumb))in the view. You can replace:thumbwith:medium` (from the above model example) or any other custom param/size you may have specified.

2 Responses
Add your response

Thank you for sharing, Rory. Just one question: should I add/modify any policy to the created bucket or leave everything as default ? Thank you.

over 1 year ago ·

Hello Rory,

I am doing exactly the same. And I have added turbolinks v5 for up- and download to paperclip v5 and aws-sdk v2. Then I get a namespace error for "AWS" in paperclip, though aws-sdk v2 has namespace "Aws". Please have a look at my question at stackoverflow here:

http://stackoverflow.com/questions/42087502/how-to-configure-rails-5-paperclip-5-aws-sdk-2-on-heroku-properly

Thank you in advance
Gerrit

over 1 year ago ·