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.

364 CHAPTER 13 Designing an API<br />

error = { :error => "You must be an admin to do that." }<br />

warden.custom_failure!<br />

render params[:format].to_sym => error<br />

, :status => 401<br />

end<br />

end<br />

end<br />

Here you use warden.custom_failure! to inform Warden (the Rack backend to<br />

Devise) that you’re going to raise a custom 401 response. Without this, Devise would<br />

instead take over from this 401 response, showing a “You must be signed in to continue”<br />

error message.<br />

You also use the render method in a unique manner here. You call it and pass in a<br />

hash with the key being a symbolized version of the format (in this case, json) and the<br />

value being the hash that contains the error. By calling render in this way, Rails will<br />

convert the hash to JSON, or if it were an XML request, to XML. The reason for doing<br />

it this way rather than using respond_with is because respond_with will attempt to do<br />

some weird behavior and doesn’t work for POST requests, so you must work around<br />

that little issue.<br />

By specifying the status option to the render here, your response’s status code<br />

will be set to that particular status, which will let the code used to connect to the API<br />

know that the user is unauthorized to perform the specific request.<br />

Now all you need to do is add this as a before_filter into app/controllers/api/<br />

v1/projects_controller.rb using this line:<br />

before_filter :authorize_admin!, :except => [:index, :show]<br />

With this line in the ProjectsController, any request to any action that’s not the<br />

index or show action will have the admin check run before it. If a user doesn’t meet<br />

this criteria, then you will return the “You must be an admin to do that” error. These<br />

pieces of code should be enough to get your test running, so let’s find out with bin/<br />

rspec spec/api/v1/project_errors_spec.rb:<br />

1 example, 0 failures<br />

Now when people who aren’t admins try to create a project, they will see the “You<br />

must be an admin to do that” error message returned from the API. Because this is the<br />

case, you’ll need to set up the user in the projects API examples to be an admin when<br />

they attempt to create a project, which you can do by putting this before after the<br />

beginning of the “creating a project” context block:<br />

before do<br />

user.admin = true<br />

user.save<br />

end<br />

When you run bin/rspec spec/api/v1/projects_spec.rb, all the examples will be<br />

passing:<br />

4 examples, 0 failures

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

Saved successfully!

Ooh no, something went wrong!