Setting up image upload with Cloudinary, Rails and Active Storage
This guide will walk you through the steps to setup simple image uploading in Rails using cloudinary service and ActiveStorage.
You can reference all documentation here:
Ruby-on-Rails SDK– Upload + Image, Video Transformations | Cloudinary
Active Storage integration | Cloudinary
Active Storage Overview — Ruby on Rails Guides
Installing Cloudinary's SDK
Let's start by installing Cloudinary's SDK for rails:
In your Gemfile
insert the following line:
gem 'cloudinary'
And then run bundle
.
Setting up your Cloudinary credentials
After installing, you'll need to setup all needed credentials and other useful variables that will be sent in each upload request to cloudinary apis.
There's a few options, and the one we are going to use here is by creating a file inside the config
folder called cloudinary.yml
You can download a pre-customized using this link: cloudinary.yml
If you couldn't download the file, you need this basic set of configuration to get you started:
development: cloud_name: <%= ENV['CLOUDINARY_CLOUD_NAME'] %> api_key: <%= ENV['CLOUDINARY_API_KEY'] %> api_secret: <%= ENV['CLOUDINARY_API_SECRET'] %> enhance_image_tag: true static_file_support: false
It's good to make use of environment variables to put your credentials in this file. You can easily manage env variables using the dotenv gem
Setting up Rails Active Storage
Setting up Active Storage is fairly simple, but you'll need to have either ImageMagick or libvips installed since Rails relies on one of these libs for image analysis and transformations.
If you're gonna handle image/video or PDF previews, you'll also need other libs.
Your can see the full list of requirements here.
In order to work properly, active storage will need to work with three tables in your application: active_storage_blobs
, active_storage_variant_records
and active_storage_attachments
.
Don't worry cause you don't need to manually create and set them up. Just run rails active_storage:install
to generate the migration file and as always, run rail db:migrate
.
There's some additional notes about how this tables work and how they will be used across your application. It's worth taking a look, specially if you use UUIDs instead of integers as primary keys.
Setting Up Cloudinary with Active Storage
Now we are ready to setup Cloudinary to be used by Active Storage.
Head to your config/storage.yml
to create a cloudinary service.
cloudinary: service: Cloudinary folder: MEDIA_FOLDER_NAME_YOU_CREATED_IN_CLOUDINARY
Don't forget to change MEDIA_FOLDER_NAME_YOU_CREATED_IN_CLOUDINARY with a valid folder name you setup in your cloudinary dashboard.
Now let's tell Active Storage that we want to use this cloudinary service.
In config/environments/development.rb
put the following inline:
config.active_storage.service = :cloudinary
Note: This line is probably already declared in this file as
config.active_storage.service = :local
, so you just to replace the assignment withcloudinary
.
Associating image file with application Model
Let's say that our application has a Publication
entity that the user can create with a thumbnail
image.
Add has_one_attached :thumbnail
to your publication.rb
file.
This is a case where the entity has ONE file associated with a column.
If you need to storage and handle multiple images take a look has_many_attached
In your view file, inside your form, create a simple file input:
<%= form.file_field :thumbnail %>
Now, inside your controller, that handles the form submission, you can do the following:
@publication = News.create params # any other param your entity may need @publication.thumbnail.attach(params[:thumbnail])
And you can render your image like this:
<img src="<%= publication.thumbnail.attachment.url %>" alt="A nice alt value" />
Here are more useful references to work with model attachments:
ActiveStorage::Blob (rubyonrails.org)