Share This Article
In this article, we’ll show you how to use Paperclip in Rails to add images processing them.
Paperclip is a gem used for image processing in Ruby. It is one of the most popular image processing gems and has been used by projects like GitHub, Shutterstock, and thoughtbot.
How to install Paperclip
To install Paperclip, add it to your Gemfile and run the bundle
command to install it.
gem "paperclip", "~> 5.1.0"
How to use Paperclip
Paperclip is typically used with ActiveRecord, so we’ll use it with a Ruby on Rails project.
First, we need to generate a model to store the image. We’ll use the rails generate
command to generate a model with an avatar
field.
rails generate model User avatar
This will generate a model with a has_attached_file :avatar
line and a migration to add an avatar_file_name
field to the database.
How to add an avatar to a User
Next, we need to add an avatar
field to our form so that users can upload an image.
We can use the file_field
helper to do this.
<%= form_for @user do |f| %>
<%= f.file_field :avatar %>
<%= f.submit %>
<% end %>
This will add a file upload field to our form.
How to upload an avatar
Now we can upload an image, but we need to process it with Paperclip first.
In our controller, we can add a before_action
to process the uploaded image.
class UsersController < ApplicationController
before_action :set_user, only: [:show, :edit, :update, :destroy]
before_action :upload_avatar, only: [:create, :update]
def new
@user = User.new
end
def create
@user = User.new
if @user.save
redirect_to @user
else
render :new
end
end
def upload_avatar
if params[:user][:avatar]
@user.avatar = params[:user][:avatar]
end
end
end
We need to whitelist the avatar
field in our controller as well.
class UsersController < ApplicationController
before_action :set_user, only: [:show, :edit, :update, :destroy]
before_action :upload_avatar, only: [:create, :update]
def user_params
params.require(:user).permit(:avatar)
end
end
Now we can upload an image, which will be processed with Paperclip.
How to add image processing to Paperclip
Paperclip can do a lot more than just uploading images. It can also resize, crop, and watermark images.
To do this, we need to add some processing options to our model.
class User < ApplicationRecord
has_attached_file :avatar, styles: {
thumb: "100x100>",
medium: "300x300>",
large: "600x600>"
}
end
This will generate three versions of the image (thumb, medium, and large) and resize them to fit within the given dimensions.
We can also crop images.
class User < ApplicationRecord
has_attached_file :avatar, styles: {
thumb: ["100x100#", :png],
medium: ["300x300#", :jpg],
large: ["600x600#", :png]
}
end
This will create three versions of the image (thumb, medium, and large) and crop them to fit within the given dimensions.
We can also watermark images.
class User < ApplicationRecord
has_attached_file :avatar, styles: {
thumb: { geometry: "100x100#", format: :png, convert_options: "-background '#000C' -gravity center -composite -depth 8" },
medium: { geometry: "300x300#", format: :jpg, convert_options: "-background '#000C' -gravity center -composite -depth 8" },
large: { geometry: "600x600#", format: :png, convert_options: "-background '#000C' -gravity center -composite -depth 8" }
}
end
This will create three versions of the image (thumb, medium, and large) and watermark them with the given image.
How to validate images with Paperclip
We can also validate images with Paperclip.
class User < ApplicationRecord
has_attached_file :avatar
validates_attachment_content_type :avatar, content_type: /\Aimage\/.*\z/
end
This will validate that the uploaded image is an image.
We can also validate the file size.
class User < ApplicationRecord
has_attached_file :avatar
validates_attachment_content_type :avatar, content_type: /\Aimage\/.*\z/
validates_attachment_size :avatar, in: 0..5.megabytes
end
This will validate that the uploaded image is in the given range (0 to 5 MB).
How to use Paperclip with S3 We can also use Paperclip with S3 for storage.
First, we need to add the aws-sdk
gem to our Gemfile.
gem "aws-sdk"
Next, we need to configure Paperclip to use S3 for storage. We can do this in an initializer.
Paperclip::Attachment.default_options[:storage] = :s3
Paperclip::Attachment.default_options[:s3_protocol] = "https"
Paperclip::Attachment.default_options[:s3_credentials] = {
bucket: ENV["S3_BUCKET_NAME"],
access_key_id: ENV["AWS_ACCESS_KEY_ID"],
secret_access_key: ENV["AWS_SECRET_ACCESS_KEY"],
s3_region: ENV["AWS_REGION"],
}
We need to set the :s3_protocol
to https
because S3 doesn’t support HTTP.
We also need to set the :s3_credentials
to our S3 credentials. We can set these in our .env
file.
S3_BUCKET_NAME=your-bucket-name
AWS_ACCESS_KEY_ID=your-access-key-id
AWS_SECRET_ACCESS_KEY=your-secret-access-key
AWS_REGION=your-region
Now Paperclip will upload files to S3 instead of the local filesystem.
How to delete images with Paperclip
We can also delete images with Paperclip.
class User < ApplicationRecord
has_attached_file :avatar
before_destroy :destroy_avatar
def destroy_avatar
self.avatar = nil
end
end
This will delete the image from S3 when the User is destroyed.
We can also delete the image from the local filesystem.
class User < ApplicationRecord
has_attached_file :avatar, styles: {
thumb: { geometry: "100x100#", format: :png, convert_options: "-background '#000C' -gravity center -composite -depth 8" },
medium: { geometry: "300x300#", format: :jpg, convert_options: "-background '#000C' -gravity center -composite -depth 8" },
large: { geometry: "600x600#", format: :png, convert_options: "-background '#000C' -gravity center -composite -depth 8" }
}
before_destroy :destroy_avatar
def destroy_avatar
self.avatar.destroy
end
end
This will delete the image from the local filesystem when the User is destroyed.
How to use Paperclip with a CDN
We can also use Paperclip with a CDN.
Paperclip::Attachment.default_options[:url] = ":s3_domain_url"
Paperclip::Attachment.default_options[:path] = "/:class/:attachment/:id_partition/:style/:filename"
Paperclip::Attachment.default_options[:s3_host_name] = "s3-#{ENV['AWS_REGION']}.amazonaws.com"
This will configure Paperclip to use a CDN.
Conclusion
Paperclip is a great gem for image processing in Ruby. It can upload, resize, crop, and watermark images.
For more information on the Paperclip, check out the paperclip GitHub page.