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.

236 CHAPTER 9 File uploading<br />

When you pass the :locals option to render, you can set local variables that can be<br />

used in the partial. Local variables in views are usable only in the views or partials in<br />

which they’re defined unless you pass them through by using this :locals. You pass<br />

through the number of your file field and the asset object provided by fields_for<br />

:assets.<br />

To get the new action to render this partial, you can use the same code in the new<br />

action in FilesController but with a small change:<br />

def new<br />

asset = Asset.new<br />

render :partial => "files/form",<br />

:locals => { :asset => asset }<br />

end<br />

Here you must pass the name of the partial using the :partial option so the controller<br />

will attempt to render a partial. If you left it without the option, the controller<br />

would instead try to render the template at app/views/files/form.html.erb, which<br />

doesn’t exist.<br />

Before this line, you need to set up the asset variable that you reference. Add<br />

these two lines directly above the first line inside the new action:<br />

@ticket = Ticket.new<br />

asset = @ticket.assets.build<br />

Because the Ticket object for your form is only a new record, it isn’t important precisely<br />

what object it is: all new Ticket objects are the same until they’re saved to the<br />

database and given a unique identifier. You can exploit this by creating another<br />

Ticket object and building your new asset from it.<br />

It makes sense to do this because in your app/views/files/_form.html.erb file, you<br />

still reference the now-nonexistent f variable, which came from form_for @ticket in<br />

app/views/tickets/new.html.erb. Again, you can exploit the fact that all new Ticket<br />

objects are the same and use a fields_for instead of a form_for in this partial to get<br />

it to give the file field a proper name. Without this fields_for, the name of the field<br />

would be something like asset[asset], and you need it to be something more like<br />

ticket[asset_attributes][0][asset]. Now change the app/views/files/_form<br />

.html.erb partial to look like the following listing.<br />

Listing 9.15 app/views/files/_form.html.erb<br />

<br />

number do |asset| %><br />

<br />

<br />

<br />

<br />

<br />

<br />

The @ticket object here could either be from the new action in the Tickets-<br />

Controller or from the new action in the FilesController: it doesn’t matter.

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

Saved successfully!

Ooh no, something went wrong!