Rails' link_to method: GETing when it should DELETE
I'm following Michael Hartl's Rails Tutorial, and for some reason the following code:
<%= link_to 'delete', user, :method => :delete, :confirm => "You sure?",
:title => "Delete #{user.name}" %>
Issues a GET request (as I verified by checking the rails server log). I also verified that the following line is in my application view:
<%= javascript_include_tag :all %>
One thing I didn't quite understand, and it's probably the source of my problem: where is the "delete" method defined? I verified in Hartl's source code that he defines a "destroy" method in the controller, not "delete". But even if I change the link_to to :method => :destroy, it just issues a GET.
I'm using Rails 3.1. Any tips?
Solution 1:
Also check that this is in your application.js:
//= require jquery
//= require jquery_ujs
Apparently I had the jquery without the jquery_ujs and I had the same problem until I added that.
Solution 2:
Most browsers don't actually support the DELETE verb, so Rails fakes it by modifying the HTML it generates. Rails tacks on a HTML5 attribute called data-method
and sets it to "delete"
. So when a user clicks on the link, it is actually issued as a GET
request, but the data-method
attribute allows for some Rails magic and means your routing code should recognize it as a DELETE request.
edit:
You can test it yourself in the console. Run bundle exec rails c
to get into the console, and look at the HTML that this generates:
helper.link_to "delete", "foobar/delete", :method => 'delete'
The HTML should look like this:
<a href="foobar/delete" data-method="delete" rel="nofollow">delete</a>
Solution 3:
You should use the following code
<%= button_to "delete", @user_current, :method => "delete" %>
It will solve the problem or add this line //= require jquery_ujs to application.js and use:
<%= link_to 'delete', user, :method => :delete, data: {:confirm => "You sure?" } ,
:title => "Delete #{user.name}" %>
Solution 4:
As browsers don't support the DELETE
verb, Rails creates a workaround for this problem by simulating a DELETE
request through a standard GET
or POST
. The way method: :delete
works is with a JavaScript handler for all links with data-method="delete"
which modifies the request so Rails
processes it as a DELETE. This JavaScript handler is provided by the jquery_ujs
library.
There are several things that could have gone wrong:
- Make sure you have both
jquery
andjquery_ujs
included in yourapplication.js
. Without both nothing will process the data attributes. - Make sure the link in question really has the
method: :delete
option specified. - Make sure for some reason you haven't stopped the event propagation of the link in question, like so for example:
$( 'a' ).click( function( event ) {
event.stopPropagation()
})
As this would prevent the jquery_ujs
handlers from being executed and the request will never be modified and will remain just a standard GET.