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.

Restricting actions to admins only<br />

changes. To fix this problem, use RSpec.configure in another file: spec/support/<br />

devise.rb. RSpec automatically loads files in this directory. Let’s create this file now and<br />

fill it with the content from the following listing.<br />

Listing 7.6 spec/support/devise.rb<br />

RSpec.configure do |config|<br />

config.include Devise::TestHelpers<br />

end<br />

You should include this module only for controller tests by passing a filter to the end:<br />

config.include Devise::TestHelpers, :type => :controller<br />

If you don’t restrict where this module is included, it could lead to problems further<br />

down the line. It’s better to be safe than sorry.<br />

TIP You can specify :type => :model as a filter if you want to include a<br />

module only in your model specs. If you ever write any view specs, you can<br />

use :type => :view to include this module only in the view specs. Similarly,<br />

you can use :controller for controller specs.<br />

Going back to your spec, you make a request on the third line to the new action in the<br />

controller. The before_filter that you haven’t yet implemented should catch the<br />

request before it gets to the action; it won’t execute the request but instead redirects<br />

the user to root_path and shows a flash[:alert] saying the user “must be an admin<br />

to do that.”<br />

If you run this spec with bin/rspec spec/controllers/projects_controller<br />

_spec.rb, it fails as you expect:<br />

Failure/Error: response.should redirect_to(root_path)<br />

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

This error message tells you that although you expected to be redirected, the<br />

response was actually a 200 response, indicating a successful response. This isn’t what<br />

you want. Now let’s get it to pass.<br />

The first step is to define a new method that checks whether a user is an admin,<br />

and if not, displays the “You must be an admin to do that” message and then redirects<br />

the requester to the root_path. First define this new method inside app/controllers/<br />

application_controller.rb, which is the base class for all controllers and makes any<br />

methods defined here available to all controllers. Define the method using the following<br />

listing inside the ApplicationController class.<br />

Listing 7.7 app/controllers/application_controller.rb<br />

private<br />

def authorize_admin!<br />

authenticate_user!<br />

unless current_user.admin?<br />

141

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

Saved successfully!

Ooh no, something went wrong!