27.02.2013 Views

Rails%203%20In%20Action

Rails%203%20In%20Action

Rails%203%20In%20Action

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

Serving files through a controller<br />

asset = Asset.find(params[:id])<br />

send_file asset.asset.path, :filename => asset.asset_file_name,<br />

:content_type => asset.asset_content_type<br />

end<br />

end<br />

In this action, you find the Asset object by using the params[:id] the action receives.<br />

Then you use the asset object in combination with the send_file method to send<br />

the file back as a response rather than a view in your application.<br />

The first argument for send_file is the path to the file you’re sending. The next<br />

argument is an options hash used to pass in the filename and content_type options<br />

so the browser receiving the file knows what to call it and what type of file it is.<br />

To route requests to this controller, you need to define a route in your config/<br />

routes.rb file, which you can do with this line:<br />

resources :files<br />

When you run the specs for this controller again using bin/rspec spec/controllers<br />

/files_controller_spec.rb, the first spec passes, but the second one fails:<br />

FilesController users without access cannot access assets in this project<br />

...<br />

Expected response to be a , but was .<br />

The show action doesn’t redirect as this example expects because you’re not doing<br />

any permission checking in your action, which is what this example is all about:<br />

“users without access cannot access assets in this project.” To fix this problem,<br />

check that the user has permission to access this asset’s project by using the CanCan<br />

helpers you used in chapter 8. You can use them in your show action now, as shown in<br />

the following listing.<br />

Listing 9.12 app/controllers/files_controller.rb<br />

def show<br />

asset = Asset.find(params[:id])<br />

if can?(:view, asset.ticket.project)<br />

send_file asset.asset.path, :filename => asset.asset_file_name,<br />

:content_type => asset.asset_content_type<br />

else<br />

flash[:alert] = "The asset you were looking for could not be found."<br />

redirect_to root_path<br />

end<br />

end<br />

Now when you rerun these specs, you’re missing a method:<br />

undefined method 'ticket' for #<br />

This method is a simple belongs_to, which you must define inside the Asset model:<br />

belongs_to :ticket<br />

229

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

Saved successfully!

Ooh no, something went wrong!