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.

Linking tickets to users<br />

Then I should see "You need to sign in or sign up before continuing."<br />

When I fill in "Email" with "user@ticketee.com"<br />

And I fill in "Password" with "password"<br />

And I press "Sign in"<br />

Then I should see "New Ticket"<br />

The step that checks for the text “You need to sign in or sign up before continuing”<br />

fails because you’re not ensuring the user is signed in before the new action in the<br />

TicketsController.<br />

To do so, you can use the Devise-provided method authenticate_user! as a<br />

before_filter. Put this method directly underneath the class definition for Tickets-<br />

Controller inside app/controllers/tickets_controller.rb. The placement of this<br />

before_filter ensures that if it fails, the other two before_filters underneath it<br />

will not needlessly run, eventually saving valuable CPU cycles.<br />

The line you put in the TicketsController is<br />

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

This line ensures that users are authenticated before they go to any action in the controller<br />

that isn’t the index or show, including the new and create actions.<br />

By ensuring this authentication, you’ll know which user created a ticket during the<br />

creation process, so let’s link tickets to users.<br />

6.5.1 Attributing tickets to users<br />

To link tickets to specific users, you alter the build line in your create action in<br />

TicketsController from this line<br />

@ticket = @project.tickets.build(params[:ticket])<br />

to this:<br />

@ticket = @project.tickets.build(params[:ticket].merge!(:user => current_user))<br />

The merge! method here is a Hash and HashWithIndifferentAccess method, which<br />

merges the provided keys into the hash and overrides any keys already specified. 2<br />

When you run the feature again using bin/cucumber features/creating_tickets<br />

.feature, it complains about an unknown attribute in all three scenarios:<br />

unknown attribute: user (ActiveRecord::UnknownAttributeError)<br />

This error occurs because you haven’t added a belongs_to association between the<br />

Ticket and User. Let’s open app/models/ticket.rb and add this line directly under the<br />

belongs_to :project line:<br />

belongs_to :user<br />

The belongs_to method defines methods for accessing the association, as has_many<br />

does, except here you retrieve only one record. Active Record knows which record<br />

to retrieve when you call either project or user on a Ticket object because it<br />

2 Which could happen if someone hacked the form and attempted to pass their own user attribute.<br />

129

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

Saved successfully!

Ooh no, something went wrong!