15: Using attachments for images
If you have a website where people can post stories, useful advice or other textual stuff, it is very likely that soon they will want to have the possibility to attach some pictures to their posts.
There are a couple of things that we have to think about when planning to add images to our cases, mainly how to upload and how to store them. Fortunately there are services that can handle this for us.
Today we are going to use Cloudinary, a CDN (content delivery network) for working with images, which integrates nicely with Ruby on Rails.
So let us start out by creating a Cloudinary account. Go to http://cloudinary.com, and sign up.
Now you can login into Cloudinary and access your dashboard at https://cloudinary.com/console where you can find information about your account, as well as the secret keys that your app should use in order to access the service.
To make our app work with Cloudinary, we need to perform the following things:
- Add a line to the
Gemfilein the root of your project:
- Bundle your gems by running in the terminal in the folder of your project:
$ bundle install
- Download the
cloudinary.ymlconfiguration file. You can do it also by navigating to your Cloudinary Dashboard and clicking the little
YMLlink in the image below or following https://cloudinary.com/console/cloudinary.yml:
- Move this file to the
config/folder of your project.
At this point, we can use the
cl_image_tag helper in our views in order to reference images hosted on Cloudinary.
However, we still lack the upload functionality. We will use another gem, called attachinary for managing our uploads and attachments.
There is a little bit more work to put in configuring this gem:
- Add the this line to the
Gemfile(you can put it near the 'cloudinary' gem):
Bundle the gems once again:
$ bundle install
config/application.rbfile and insert just after the line with
require 'rails/all'the following:
- Configure the database for attachments by runing these rake tasks:
$ rake attachinary:install:migrations $ rake db:migrate
- In the
config/routes.rbfile, just after
mount Attachinary::Engine => '/attachinary'
- In the
<%= csrf_meta_tags %>insert:
<%= cloudinary_js_config %>
- At last, in the
//= require turbolinks:
//= require cloudinary/jquery.cloudinary //= require attachinary
Adding pictures to posts
Now that we have configured the gems and have run the necessary migrations, we can add a picture to our post with just one line of code. Suppose we have a Case model in the file
app/models/case.rb which looks like this:
class Case < ActiveRecord::Base belongs_to :user end
In order to add an image to it, add a line that declares an attachment with the specified name:
class Case < ActiveRecord::Base has_attachment :case_image belongs_to :user end
Our model is ready to accept images as attachments, but we didn't provide the appropriate upload button in the form for creating a new post. Let's do it now:
Open the file
app/views/cases/new.html.erb and insert before
<%= form.button :submit %> (the submit button), a button for uploading images:
<%= form.attachinary_file_field :case_image %>
There is still one thing to do until we can enjoy the fun of uploading pictures to our site. We have to display them to the user.
As noted above, in order to display an image from Cloudinary we have to use the
cl_image_tag helper instead of the standard
app/views/cases/index.html.erb, find the line that states:
<%= image_tag(c.image_link, width: 600 ) %>
And replace it with the new one:
<%= cl_image_tag(c.case_image.path, width: 600) %>
Congratulations! Your users can now attach images to their posts!
However, if we start the server, then try to load the cases page (by going to
http://localhost:3000/cases, we see the following:
This is because none of our previous cases do not have an image property, since the images were provided as a link, but not an upload.
The easiest way is to remove all the previous posts. Open the Rails console (
rails console), and type:
We deleted all the content and we have to make new cases now.
Refresh the page, click your version of "Create a new case" link, click Choose file, upload a photo and you should see it on the page.