How to test Paperclip uploads in Rails4

When testing Paperclip uploads in my application, I’m interested in treating Paperclip as a black box and trusting it for doing its magic. So what I really need to test is that valid files are processed and invalid ones are not. (see How to allow users to crop images in Rails 4 for model and controller code)

Tests for the model:

{[ .model-tests | 1.hljs(=ruby=) ]}

Tests for the controller:

{[ .controller-tests | 1.hljs(=ruby=) ]}

 

How to allow users to crop images in Rails 4

For cropping images I use Jcrop, a plugin for jQuery. It works pretty well and there are already some tutorials for integrating it into a Rails app. So this post is almost a simple update to what’s already available in the internet. What follows is just my setup.

1: create an Upload model, i.e. a class for holding uploaded files, not only images. This is fairly straightforward.

{[ .migration-basic | 1.hljs(=ruby=) ]}

{[ .upload-class-basic | 1.hljs(=ruby=) ]}

2: attach Paperclip to the Upload model.

{[ .gem-cargo | 1.hljs(=ruby=) ]}

{[ .migration-cargo | 1.hljs(=ruby=) ]}

Note that in my setup, contrary to what’s generally advised, I’m trashing the really original image in favor of a (small and) predictable version of it. (width, height and weight)

{[ .upload-class-cargo | 1.hljs(=ruby=) ]}

3: add exif data support

{[ .gem-exif | 1.hljs(=ruby=) ]}

{[ .migration-exif | 1.hljs(=ruby=) ]}

{[ .upload-class-exif | 1.hljs(=ruby=) ]}

4: add cropping support

Jcrop must be installed in Rails.

  1. I added a /vendor/assets/jquery-jcrop/0.9.2 directory with all of its files in it.
  2. I copied js/jquery-Jcrop.js, css/jquery-Jcrop.css and Jcrop.gif into the /vendor/assets/jquery-jcrop directory.
  3. I added a = require jquery.Jcrop line into both the /app/assets/javascripts/application.js and /app/assets/stylesheets/application.css manifests.

{[ .manual-thumbnail | 1.hljs(=ruby=) ]}

{[ .migration-crop | 1.hljs(=ruby=) ]}

{[ .upload-class-crop | 1.hljs(=ruby=) ]}

5: modify the generated controller such that

  1. all necessary params are whitelisted
  2. upon image creation the user is given a chance to crop it
  3. upon image update it gets cropped

{[ .uploads-controller | 1.hljs(=ruby=) ]}

6: modify the form helper

{[ .form-helper | 1.hilite(=html=) ]}

7: modify the show template

{[ .show-template | 1.hilite(=html=) ]}