27.02.2013 Views

Rails%203%20In%20Action

Rails%203%20In%20Action

Rails%203%20In%20Action

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

216 CHAPTER 9 File uploading<br />

that the form is multipart anyway, so you should do this now by changing the<br />

form_for line in app/views/tickets/_form.html.erb from this<br />

<br />

to this:<br />

{ :multipart => true } do |f| %><br />

Now we come to a very interesting point in implementing file uploading. When you<br />

run bin/cucumber features/creating_tickets.feature, all of the scenarios are<br />

broken and all for the same reason:<br />

And I press "Create Ticket"<br />

unknown attribute: asset (ActiveRecord::UnknownAttributeError)<br />

Because you added this file_field, the create action’s code dutifully tries to assign<br />

it as an attribute, only to find that it’s not defined and so causes this error. Rather than<br />

running a migration to add an attribute by this name, you use the Paperclip gem to<br />

handle it.<br />

9.1.2 Enter stage right, Paperclip<br />

Just as you would use a normal paperclip to attach paper files together, in your application<br />

you use the Paperclip gem to provide the attachment functionality you need<br />

for tickets. This gem was created by thoughtbot, 4 which has a whole slew of other useful<br />

gems, such as Hoptoad. 5<br />

To install Paperclip, you need to add a line to the Gemfile to tell Bundler that you<br />

want to use this gem. Put this underneath the line specifying the CanCan gem, separated<br />

by a line because it’s a different type of gem (CanCan has to do with users,<br />

paperclip has to do with files):<br />

gem 'cancan'<br />

gem 'paperclip'<br />

Next, you must run bundle install to install this gem.<br />

With Paperclip now installed, you can work on defining the asset attribute that<br />

your model wants. It’s not really an attribute; the error message is misleading in that<br />

respect. All it needs is a setter method (asset=) and it would be happy. But you need<br />

this method to do more than set an attribute on this object; you need it to accept the<br />

uploaded file and store it locally. Paperclip lets you define this fairly easily with its<br />

has_attached_file method. This method goes in the Ticket model, defines the setter<br />

method you need, and gives four application the ability to accept and process this<br />

file. Add it to your Ticket model with this line:<br />

has_attached_file :asset<br />

Now this asset= method is defined, but it’s not yet over!<br />

4 http://thoughtbot.com.<br />

5 For a full list of thoughtbot’s gems, see its GitHub page: http://github.com/thoughtbot.

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!