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.

Restricting by scope<br />

The :as option on the has_many :permissions association B links your projects to<br />

the thing association on the Permission objects. You need this association defined<br />

here because it’s used by the scope below it.<br />

Usually, you use scope without passing a block (represented by the lambda), but<br />

here the outcome of this scope is dynamic according to which user is passed to it. You<br />

therefore use a block to be able to pass this argument to the method generated by the<br />

scope call, which then becomes available in the block for use in the where statement.<br />

The joins method here joins the permissions table using a SQL INNER JOIN,<br />

allowing you to perform queries on columns from that table too. You do just that with<br />

the where method, specifying a hash that contains the permissions key, which points<br />

to another hash containing the fields you want to search on and their expected values.<br />

This scope then returns all the Project objects containing a related record in the<br />

permissions table that has the action field set to view and the user ID equal to that<br />

of the passed-in user.<br />

With this scope method in place, when you run this spec file again with bin/<br />

rspec spec/controllers/projects_controller_spec.rb, your tests pass because<br />

you’re now scoping down the find in the find_project method. But you still have<br />

one failure:<br />

7 examples, 1 failure<br />

This failing spec is the last one in this file where you assert that users receive the message<br />

“The project you were looking for could not be found” if they attempt to access a<br />

project that is unknown to the system. It fails with this error:<br />

Expected response to be a redirect to <br />

but was a redirect to <br />

Rather than redirecting back to /projects as it should, this code now redirects to the<br />

/users/sign_in path. This would happen only if the user attempted to access an<br />

action that you had locked down to be visible only to those who were signed in.<br />

Recent changes to the show action fit this bill: users are now required to sign in before<br />

you run the find_project method.<br />

Therefore, you just need to make a small fix to this final spec: you must sign in as a<br />

user before you make the get :show request. Let’s change the first two lines of this<br />

spec in spec/controllers/projects_controller.rb from this<br />

it "displays an error for a missing project" do<br />

get :show, :id => "not-here"<br />

to this:<br />

it "displays an error for a missing project" do<br />

sign_in(:user, user)<br />

get :show, :id => "not-here"<br />

Now when you run bin/rspec spec/controllers/projects_controller_spec.rb,<br />

all the examples pass:<br />

171

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

Saved successfully!

Ooh no, something went wrong!