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.

224 CHAPTER 9 File uploading<br />

9.2.2 Using nested attributes<br />

You used the term Asset rather than File throughout this application because of this<br />

model. You can’t define a File model because there’s already a File class in Ruby.<br />

Asset is an alternative name you can use. To define this Asset constant in your application,<br />

you can run the model generator:<br />

rails g model asset<br />

Each record for this model refers to a single file that has been uploaded to a ticket.<br />

Therefore, each record in the assets table must have the same asset_* fields that<br />

each tickets record currently has. Storing the asset references in the assets table<br />

now makes the references in the tickets table irrelevant, so you should remove them.<br />

You should also add a relationship between the asset records and the ticket records by<br />

adding a ticket_id field to the assets table. Open the migration this generates, and<br />

change it to the following listing to reflect these ideas.<br />

Listing 9.7 db/migrate/[date]_create_assets.rb<br />

class CreateAssets < ActiveRecord::Migration<br />

def change<br />

create_table :assets do |t|<br />

t.string :asset_file_name<br />

t.integer :asset_file_size<br />

t.string :asset_content_type<br />

t.datetime :asset_updated_at<br />

t.integer :ticket_id<br />

t.timestamps<br />

end<br />

[:asset_file_name,<br />

:asset_file_size,<br />

:asset_content_type,<br />

:asset_updated_at].each do |column|<br />

remove_column :tickets, column<br />

end<br />

end<br />

end<br />

Run this migration with rake db:migrate to migrate your development environment’s<br />

database, and then run rake db:test:prepare to migrate the test environment’s database.<br />

When you run the feature again with bin/cucumber features/creating<br />

_tickets.feature:36, your File #1 field is once again missing:<br />

And I attach the file "spec/fixtures/speed.txt" to "File #1"<br />

cannot attach file, no file field with id, name,<br />

or label 'File #1' found (Capybara::ElementNotFound)<br />

You’ve gone backward! Or so it seems.<br />

As mentioned earlier, fields_for detects that the assets method is defined on<br />

your Ticket object and then iterates through each object in this collection while rendering<br />

the fields inside fields_for for each. When you create a new ticket in

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

Saved successfully!

Ooh no, something went wrong!