Goals
- Learn to treat files as an ActiveRecord attribute type, like
:string
or:integer
Research
- Look at the README for the carrierwave Show archive.org snapshot gem
- Read about Common mistakes when storing file uploads with Rails
- Carrierwave: How to attach files in tests
- Carrierwave: Built-in RSpec matchers
- CarrierWave: Processing images with libvips
- Multipart formposts Show archive.org snapshot
- Content Disposition Header Show archive.org snapshot
Exercise
In MovieDB, allow movie authors to upload a movie poster using the carrierwave
gem:
- The poster should be uploaded in the form where we can also fill in title, year, etc.
- On the movie show view, render a poster version that is 400 pixel wide, with a height that respects the aspect ratio of the original image
- On the movie index view, render a poster version that is 100 pixel wide and cropped to 100 pixel height, regardless of the original aspect ratio. The image should be cropped to the square aspect ratio, not distorted.
- On the movie show view, offer a link to download the original poster image file.
- The download link should always download the image and never display it inline within the browser window. You can do so with either the
[download]
HTML attribute, or by sending aContent-Disposition
header when delivering the image. - When editing a movie, offer controls to delete or replace the poster image file.
- There should be a validation allowing only uploads of
.jpg
,.jpeg
,.png
and.webp
files. - You do not need to treat movie posters as confidential, so it's not important if an unauthorized user can see a poster.
- When saving a poster and there is a validation error on another field (e.g. missing title), the file selection should be preserved when the form is displayed again. Use the CarrierWave cache Show archive.org snapshot for this.
Make sure to add tests for adding, changing and deleting a poster image:
- An integration test for the happy path
- User uploads image, sees an image review, downloads image.
- Capybara needs the browser to show an interactive HTML page to be happy. Capybara methods will fail when the browser shows a "Save as" dialog or when it displays an inline download within the browser window. See Testing File Downloads with Selenium for alternatives.
- Unit tests for details
- Rendering of image versions and validation of file extension can be tested with RSpec
- These can be model specs for either the
Movie
or yourPosterUploader
- To save a poster, just assign any
IO
object to theMovie#poster=
setter and save the movie. - In a real HTTP request scenario, the assigned
IO
object also carries information about image's original filename and its MIME type. You can build a similar IO object like this:movie.poster = Rack::Test::UploadedFile.new('spec/fixtures/poster.jpg', 'image/jpeg')
Posted by Henning Koch to makandra Curriculum (2015-07-08 17:43)