Rails%203%20In%20Action
Rails%203%20In%20Action Rails%203%20In%20Action
esources :tickets do resources :comments resources :tags do member do delete :remove end end end Deleting a tag By nesting the tags resource inside the ticket’s resource, you are given routing helpers such as ticket_tag_path. With the member block inside the resources :tags, you can define further actions that this nested resource responds to. You’ll define that you should accept a DELETE request to a route to a remove action for this resource, which you should now create. Before you add this action to the TagsController, you must first generate this controller by using rails g controller tags Now that you have a controller to define your action in, let’s open app/controllers/ tags_controller.rb and define the remove action in it like this: def remove @ticket = Ticket.find(params[:ticket_id]) if can?(:tag, @ticket.project) || current_user.admin? @tag = Tag.find(params[:id]) @ticket.tags -= [@tag] B Remove tag @ticket.save render :nothing => true end end In this action, you find the ticket based on the id passed through as params[:ticket], and then you do something new. On the left side of -= B you have @ticket.tags. On the right, is an array containing @tag. This combination will remove the tag from the ticket, but will not delete it from the database. On the second-to-last line of this action, you save the ticket minus one tag. On the final line you tell it to return nothing, which will return a 200 OK status to your browser, signaling that everything went according to plan. When you re-run your scenario it will now successfully click the link, but the tag is still there: When I follow "delete-this-tag-must-die" Then I should not see "this-tag-must-die" Failed assertion, no message given. (MiniTest::Assertion) Your tag is unassociated from the ticket but not removed from the page, and so your feature is still failing. The request is made to delete the ticket, but there’s no code currently that removes the tag from the page. There are two problems you must overcome to make this work. The first is that there’s no code. That part’s easy, and you’ll 301
302 CHAPTER 11 Tagging get there pretty soon. The second is that there’s no unique identifier for the element rendered by app/views/tags/_tag.html.erb, which makes removing it from the page exceptionally difficult with JavaScript. Let’s add a unique identifier now and remove the element. 11.4.3 Actually removing a tag You’re removing a tag’s association from a ticket, but you’re not yet showing people that it has happened on the page. You can fix the second of your aforementioned problems by changing the span tag at the top of this partial to be this: This will give the element a unique identifier, which you can use to locate the element and then remove it using JavaScript. Currently for the remove action, you’re rendering nothing. Let’s now remove the render :nothing => true line from this action, because you’re going to get it to render a template. If a request is made asynchronously, the format for that request will be js, rather than the standard html. For views, you’ve always used the html.erb extension, because HTML is all you’ve been serving. As of now, this changes. You’re going to be rendering a js.erb template, which will contain JavaScript code to remove your element. Let’s create the view for the remove action in a file called app/views/tags/remove.js.erb, and fill it with this content: $('#tag-').remove(); This code will be run when the request to the remove action is complete. It uses the jQuery library’s $ function to locate an element with the id attribute of tag-this-tagmust-die and then calls remove() 3 on it, which will remove this tag from the page. When you run your feature using bin/cucumber features/deleting_tags .feature, you see that it now passes: 1 scenario (1 passed) 11 steps (11 passed) Awesome! With this feature done, users with permission to tag on a project will now be able to remove tags too. Before you commit this feature, let’s run rake cucumber :ok spec to make sure everything is ok: 56 scenarios (55 passed) 619 steps (619 passed) # and 39 examples, 0 failures, 19 pending That’s awesome too! Commit and push this: git add . git commit -m "Added remove tag functionality" git push 3 http://api.jquery.com/remove/.
- Page 275 and 276: 250 CHAPTER 10 Tracking state end @
- Page 277 and 278: 252 CHAPTER 10 Tracking state With
- Page 279 and 280: 254 CHAPTER 10 Tracking state which
- Page 281 and 282: 256 CHAPTER 10 Tracking state The f
- Page 283 and 284: 258 CHAPTER 10 Tracking state class
- Page 285 and 286: 260 CHAPTER 10 Tracking state Listi
- Page 287 and 288: 262 CHAPTER 10 Tracking state Listi
- Page 289 and 290: 264 CHAPTER 10 Tracking state Good,
- Page 291 and 292: 266 CHAPTER 10 Tracking state You c
- Page 293 and 294: 268 CHAPTER 10 Tracking state You h
- Page 295 and 296: 270 CHAPTER 10 Tracking state You
- Page 297 and 298: 272 CHAPTER 10 Tracking state Listi
- Page 299 and 300: 274 CHAPTER 10 Tracking state Listi
- Page 301 and 302: 276 CHAPTER 10 Tracking state def m
- Page 303 and 304: 278 CHAPTER 10 Tracking state 10.5
- Page 305 and 306: 280 CHAPTER 10 Tracking state 33 of
- Page 307 and 308: 282 CHAPTER 10 Tracking state 10.5.
- Page 309 and 310: 284 CHAPTER 10 Tracking state it "c
- Page 311 and 312: This chapter covers � Tagging spe
- Page 313 and 314: 288 CHAPTER 11 Tagging And I press
- Page 315 and 316: 290 CHAPTER 11 Tagging To define th
- Page 317 and 318: 292 CHAPTER 11 Tagging 11.2 Adding
- Page 319 and 320: 294 CHAPTER 11 Tagging 11.2.2 Fixin
- Page 321 and 322: 296 CHAPTER 11 Tagging Because the
- Page 323 and 324: 298 CHAPTER 11 Tagging ment from th
- Page 325: 300 CHAPTER 11 Tagging true, :url
- Page 329 and 330: 304 CHAPTER 11 Tagging And I follow
- Page 331 and 332: 306 CHAPTER 11 Tagging The :from op
- Page 333 and 334: 308 CHAPTER 11 Tagging This is beca
- Page 335 and 336: 310 CHAPTER 11 Tagging into this:
- Page 337 and 338: This chapter covers � Sending ema
- Page 339 and 340: 314 CHAPTER 12 Sending email To tes
- Page 341 and 342: 316 CHAPTER 12 Sending email Let’
- Page 343 and 344: 318 CHAPTER 12 Sending email Now th
- Page 345 and 346: 320 CHAPTER 12 Sending email the em
- Page 347 and 348: 322 CHAPTER 12 Sending email Great
- Page 349 and 350: 324 CHAPTER 12 Sending email messag
- Page 351 and 352: 326 CHAPTER 12 Sending email A B cr
- Page 353 and 354: 328 CHAPTER 12 Sending email Next,
- Page 355 and 356: 330 CHAPTER 12 Sending email As usu
- Page 357 and 358: 332 CHAPTER 12 Sending email When y
- Page 359 and 360: 334 CHAPTER 12 Sending email applic
- Page 361 and 362: 336 CHAPTER 12 Sending email Listin
- Page 363 and 364: 338 CHAPTER 12 Sending email To ins
- Page 365 and 366: 340 CHAPTER 12 Sending email 12.4 R
- Page 367 and 368: 342 CHAPTER 12 Sending email 12.4.2
- Page 369 and 370: 344 CHAPTER 12 Sending email When y
- Page 371 and 372: 346 CHAPTER 12 Sending email By sen
- Page 373 and 374: 348 CHAPTER 13 Designing an API One
- Page 375 and 376: 350 CHAPTER 13 Designing an API cri
esources :tickets do<br />
resources :comments<br />
resources :tags do<br />
member do<br />
delete :remove<br />
end<br />
end<br />
end<br />
Deleting a tag<br />
By nesting the tags resource inside the ticket’s resource, you are given routing helpers<br />
such as ticket_tag_path. With the member block inside the resources :tags, you can<br />
define further actions that this nested resource responds to. You’ll define that you<br />
should accept a DELETE request to a route to a remove action for this resource, which<br />
you should now create.<br />
Before you add this action to the TagsController, you must first generate this controller<br />
by using<br />
rails g controller tags<br />
Now that you have a controller to define your action in, let’s open app/controllers/<br />
tags_controller.rb and define the remove action in it like this:<br />
def remove<br />
@ticket = Ticket.find(params[:ticket_id])<br />
if can?(:tag, @ticket.project) || current_user.admin?<br />
@tag = Tag.find(params[:id])<br />
@ticket.tags -= [@tag]<br />
B Remove tag<br />
@ticket.save<br />
render :nothing => true<br />
end<br />
end<br />
In this action, you find the ticket based on the id passed through as params[:ticket],<br />
and then you do something new. On the left side of -= B you have @ticket.tags. On<br />
the right, is an array containing @tag. This combination will remove the tag from the<br />
ticket, but will not delete it from the database.<br />
On the second-to-last line of this action, you save the ticket minus one tag. On the<br />
final line you tell it to return nothing, which will return a 200 OK status to your<br />
browser, signaling that everything went according to plan.<br />
When you re-run your scenario it will now successfully click the link, but the tag is<br />
still there:<br />
When I follow "delete-this-tag-must-die"<br />
Then I should not see "this-tag-must-die"<br />
Failed assertion, no message given. (MiniTest::Assertion)<br />
Your tag is unassociated from the ticket but not removed from the page, and so your<br />
feature is still failing. The request is made to delete the ticket, but there’s no code currently<br />
that removes the tag from the page. There are two problems you must overcome<br />
to make this work. The first is that there’s no code. That part’s easy, and you’ll<br />
301