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.

Configuring Cloudinary

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:

  1. Add a line to the Gemfile in the root of your project:
    gem 'cloudinary'
    
  2. Bundle your gems by running in the terminal in the folder of your project:
    $ bundle install
    
  3. Download the cloudinary.yml configuration file. You can do it also by navigating to your Cloudinary Dashboard and clicking the little YML link in the image below or following https://cloudinary.com/console/cloudinary.yml:

  1. 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.

Configuring Attachinary

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:

  1. Add the this line to the Gemfile (you can put it near the 'cloudinary' gem):
    gem 'attachinary'
    
  2. Bundle the gems once again:

    $ bundle install
    
  3. Open the config/application.rb file and insert just after the line with require 'rails/all' the following:

    require 'attachinary/orm/active_record'
    
  4. Configure the database for attachments by runing these rake tasks:
    $ rake attachinary:install:migrations
    $ rake db:migrate
    
  5. In the config/routes.rb file, just after Rails.application.routes.draw do insert:
    mount Attachinary::Engine => '/attachinary'
    
  6. In the views/layouts/application.html.erb, before <%= csrf_meta_tags %> insert:
    <%= cloudinary_js_config %>
    
  7. At last, in the app/assets/javascripts/application.js file, insert these just before //= 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 image_tag.

In 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:

Case.destroy_all

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.

results matching ""

    No results matching ""