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.

Creating tickets<br />

inspects any array passed to helpers, such as redirect_to and link_to, and determines<br />

what you mean from the values. For this particular case, Rails determine that<br />

you want this helper:<br />

project_ticket_path(@project, @ticket)<br />

Rails determines this helper because, at this stage, @project and @ticket are both<br />

objects that exist in the database, and you can therefore route to them. The route generated<br />

would be /projects/1/tickets/2 or something similar. Back in the form_for,<br />

@ticket was new, so the route happened to be /projects/1/tickets.<br />

You could have been explicit and specifically used project_ticket_path in the<br />

action, but using an array is DRYer.<br />

When you run bin/cucumber features/creating_tickets.feature, both scenarios<br />

report the same error:<br />

And I press "Create Ticket"<br />

The action 'show' could not be found TicketsController<br />

Therefore, you must create a show action for the TicketsController, but when you<br />

do so, you’ll need to find tickets only for the given project.<br />

5.1.5 Finding tickets scoped by project<br />

Currently, the first scenario is correct, but the second one is not.<br />

Of course, now you must define the show action for your controller, but you can<br />

anticipate that you’ll need to find a ticket for the edit, update, and destroy actions<br />

too and pre-empt those errors. You can also make this a before_filter, just as you<br />

did in the ProjectsController with the find_project method. You define this<br />

finder underneath the find_project method in the TicketsController:<br />

def find_ticket<br />

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

end<br />

find is yet another association method provided by Rails when you declared that your<br />

Project model has_many :tickets. This code attempts to find tickets only within the<br />

scope of the project. Put the before_filter at the top of your class, just underneath<br />

the one to find the project:<br />

before_filter :find_project<br />

before_filter :find_ticket, :only => [:show,<br />

:edit,<br />

:update,<br />

:destroy]<br />

The sequence here is important because you want to find the @project before you go<br />

looking for tickets for it. With this before_filter in place, create an empty show<br />

action in your controller to show that it responds to this action:<br />

def show<br />

end<br />

105

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

Saved successfully!

Ooh no, something went wrong!