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.

Deleting a tag<br />

This error is coming from ticket_steps.rb, line 10. Lines 8–11 of this file look like this:<br />

table.hashes.each do |attributes|<br />

attributes.merge!(:user => User.find_by_email!(email))<br />

@project.tickets.create!(attributes)<br />

end<br />

The error is happening because the tags key in the ticket hash wants to pretend it’s<br />

a field like the other keys. In this case, it’s assuming that you’re assigning a collection<br />

of tag objects to this new ticket, and is therefore trying to iterate over each of them so<br />

that it can generate the join between this ticket and those tags. Because you’re passing<br />

it a string, it’s not going to work!<br />

You should extract this column out of this hash and use the tag! method to assign<br />

the tags, rather than attempting to create them through create!. You can modify<br />

these four lines now to look like this:<br />

table.hashes.each do |attributes|<br />

tags = attributes.delete("tags")<br />

attributes.merge!(:user => User.find_by_email!(email))<br />

ticket = @project.tickets.create!(attributes)<br />

ticket.tag!(tags) if tags<br />

end<br />

On the first line of your iteration, you use the same delete method that you’ve used a<br />

couple of times previously. This method removes the key from a hash and returns the<br />

value of that key, which you assign to the tags variable. On the final line of the iteration,<br />

call the familiar tag! method and pass in tags, thereby tagging your ticket with<br />

the passed-in tags. You use if tags because otherwise it would attempt to pass in a<br />

nil object, resulting in the nil.split error you saw earlier.<br />

When you re-run your feature using bin/cucumber features/deleting_tags<br />

.feature, it gets to the guts of your scenario and tells you that it can’t find the delete<br />

link you’re looking for:<br />

When I follow "delete-this-tag-must-die"<br />

no link with title, id or text 'delete-this_tag_must_die'<br />

Alright, time to implement this bad boy.<br />

11.4.2 Adding a link to delete the tag<br />

You need a link with the id of delete-this-tag-must-die, which is the word delete,<br />

followed by a hyphen and then the parameterize’d version of the tag’s name. This<br />

link needs to trigger an asynchronous request to an action that would remove a tag<br />

from a ticket. The perfect name for an action like this, if you were to put it in the<br />

TicketsController, would be remove_tag. But because it’s acting on a tag, a better<br />

place for this action would be inside a new controller called TagsController.<br />

Before you go and define this action, let’s define the link that your scenario is looking<br />

for first. This link goes into the tag partial at app/views/tags/_tag.html.erb inside<br />

the span tag:<br />

299

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

Saved successfully!

Ooh no, something went wrong!