ruby on rails link_to delete method not working
Asked Answered
H

10

24

I am trying to delete a post using the code below:

<%= link_to 'Destroy', post, :method => :delete, :onclick => "return confirm('Are you sure you want to delete this post?')" %>

which does not work... it simply redirects me back to the post (posts/:id}

however, if i use the following code it works

<%= button_to 'Destroy', post, method: :delete, :onclick => "return confirm('Are you sure you want to delete this post?')" %>

is it possible to make link_to behave as button_to in this case?

EDIT: destroy controller function

  def destroy
    @post = Post.find(params[:id])
    @post.destroy

    respond_to do |format|
      format.html { redirect_to posts_url }
      format.json { head :no_content }
    end
  end

log when i click the destroy button:

Started GET "/posts/14" for 127.0.0.1 at 2012-10-21 15:38:28 +0300
Processing by PostsController#show as HTML
  Parameters: {"id"=>"14"}
  Post Load (0.4ms)  SELECT `posts`.* FROM `posts` WHERE `posts`.`id` = 14 LIMIT 1
  Rendered posts/show.html.erb within layouts/application (0.6ms)
  User Load (0.4ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
Completed 200 OK in 7ms (Views: 5.4ms | ActiveRecord: 0.8ms)
[2012-10-21 15:38:28] WARN  Could not determine content-length of response body. Set content-length of the response or set Response#chunked = true

routes:

  devise_for :users

  resources :users

  resources :posts

  match '/about' => 'about#index'

  # You can have the root of your site routed with "root"
  # just remember to delete public/index.html.
  root :to => 'index#index'

  # See how all your routes lay out with "rake routes"

  # This is a legacy wild controller route that's not recommended for RESTful applications.
  # Note: This route will make all actions in every controller accessible via GET requests.
  # match ':controller(/:action(/:id))(.:format)'
  match '*a', :to => 'error#routing'
Hermelindahermeneutic answered 21/10, 2012 at 10:52 Comment(2)
Can you confirm you have the jquery-rails gem in your Gemfile? And if it is, can you also confirm via your web inspector that it's getting sent to the client browser.Telethon
yeah so when i created the rails project i removed the //= lines from app.js and that was causing the problem... thanks!Hermelindahermeneutic
H
15

Solution:

I had commented out this from application.js when i created the project

// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// the compiled file.
//
// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
// GO AFTER THE REQUIRES BELOW.
//
//= require jquery
//= require jquery_ujs
//= require_tree .

so re-adding it in solved the problem

Hermelindahermeneutic answered 21/10, 2012 at 14:36 Comment(2)
To be clear, it seems that the require jquery_ujs is the significant part, in case that's not obvious.Aube
Adding back jquery_ujs fixed exact same issue for me today. 7 years later, still the right answer. According to the docs, one of the features of jquery_ujs is that it allows you to "make non-GET requests from hyperlinks". Without this, the DELETE becomes a GET.Sleepwalk
H
33

You must be add

//= require jquery
//= require jquery_ujs

in javascripts/application.js file

second, check in layout file,

javascript_include_tag "application"

is include or not?

Hope this help.

Haunting answered 31/5, 2013 at 11:47 Comment(2)
thank you so much. I was missing //= require jquery_ujsDurfee
The Rails Guide for upgrading to 5.1 says rails_ujs is now included in rails. But though you can remove it from your Gemfile you can't remove it from here. ARRGGHH! Hours lost finding this.Goddaughter
H
15

Solution:

I had commented out this from application.js when i created the project

// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// the compiled file.
//
// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
// GO AFTER THE REQUIRES BELOW.
//
//= require jquery
//= require jquery_ujs
//= require_tree .

so re-adding it in solved the problem

Hermelindahermeneutic answered 21/10, 2012 at 14:36 Comment(2)
To be clear, it seems that the require jquery_ujs is the significant part, in case that's not obvious.Aube
Adding back jquery_ujs fixed exact same issue for me today. 7 years later, still the right answer. According to the docs, one of the features of jquery_ujs is that it allows you to "make non-GET requests from hyperlinks". Without this, the DELETE becomes a GET.Sleepwalk
S
6

Have you included this line in your layout file?

<%= javascript_include_tag "application" %>
Sordello answered 21/10, 2012 at 11:3 Comment(3)
thats in the layout file by defaultHermelindahermeneutic
And what if you replace "application" by ":defaults". Is that helpful ? <%= javascript_include_tag :defaults %>Sordello
doesn't seem to work either... my problem is not the alert thing but the fact that it doesn't delete the post... just to make sure...Hermelindahermeneutic
E
6

Firstly try checking the HTTP post method being generated in the logs. If it is "Get", it won't trigger a delete action in the controller, regardless of routes etc. It has to be a an HTTP Delete method.

In the latest versions of Rails including rails 6+, where including jquery UJS etc is not an option / easy, You should use button_to helper instead of link_to. It creates a delete HTTP post.

https://apidock.com/rails/ActionView/Helpers/UrlHelper/button_to

Erection answered 6/12, 2021 at 19:32 Comment(0)
A
3

If using link_to with :delete method you must be sure to have javascript active:

Note that if the user has JavaScript disabled, the request will fall back to using GET.

As seen in docs

If you don't want to be dependent on javascript you can use button_to instead of link_to.

Amatory answered 8/12, 2020 at 18:30 Comment(0)
M
3

It's possible to have a working link_to without jQuery

I've found the best process to make a working delete link for ruby on rails without jQuery! We need to work with 3 things:

  1. Adding destroy method in articles_controller.rb
  2. routes.rb setup
  3. LINK_TO tag

Let's Start...

Adding destroy method in articles_controller.rb

At first, we will add def destroy ... end in articles_controller.rb, lets open:

# app/controllers/articles_controller.rb

  def destroy
    @article = Article.find(params[:id])
    @article.destroy
    params[:id] = nil
    flash[:notice] = "Art has been deleted"
    redirect_to :action => :index
  end

Here

  1. in the 1st line, we're calling a variable '@article' which will find and select the ID parameters of the article on rails console from our database. Then,
  2. in 2nd line, the @article variable will make the destroy command in the console. then,
  3. in 3rd line: the id params will be deleted and
  4. in 4th line, a notice will flash in application page "Art has been deleted" and also will show in console that, found nothing in the database.
  5. In 5th line, after the destroying process completed, we will be redirected to the article index page.

This is the main factor which will give the destroying command. and make the link_to working.

Setup routes.rb

BUT WAIT We need 2 routes for the destroy page which are:

  1. A GET protocol setup
  2. A DELETE protocol setup

In routes just add:

  resources :articles, except: [:destroy] # this will add all get request links automatically except destroy link

  post '/articles/new' => 'articles#create'
  post '/articles/:id' => 'articles#update'
  post '/articles/:id/edit' => 'articles#update' # this 3 lines are needed for other forms purpose

  # we need this 2 lines for our delete link_to setup
  delete 'articles/:id/delete' => 'articles#destroy', as: 'articles_delete'
  get '/articles/:id/delete' => 'articles#destroy'
  

Here

  1. The 2nd last line is declaring the DELETE method,

    • 'articles/:id/delete' will be the link structure in post link tag (known as: anchor tag in HTML) for every single post,
    • '=>' is pointing the link structure to the controller tag which is 'articles#destroy',
    • then we defined the path text by setting ** as: 'articles_delete'** which we will use as: 'articles_delete_path' or 'articles_delete_url' in link_to tag.

Then

  1. in last line, we defined the get request for the delete link which will give us a working link like "https://2haas.com/articles/1/delete" except "/articles/1/destroy" that means we can customize our delete link from this 2 methods setup with more additional information..

Last sweetest delete output

The desired link_to tag

we can use this to get proper delete link_to tag which will work.

<%= link_to 'Delete Article', articles_delete_path, method: :delete %>
<%= link_to 'Delete Article', articles_delete_url, method: :delete %>

<% obj.each do |post| %>
<%= link_to 'Delete Article', articles_delete_path(post), method: :delete %>
<% end %>

AND that's done except jQuery

Thanks for reading this answer properly.!

HAPPY PROGRAMMINGS

Materfamilias answered 26/5, 2021 at 18:45 Comment(0)
K
1

This is the Rails way:

<%= link_to 'Destroy', post, confirm: 'Are you sure?', method: :delete %>

If the post isn't deleted then the problem lies in your controller. Are you sure you've correctly implemented the #destroy action? What's the output you're getting in your server logs?

UPDATE: Change your action to:

def destroy
  @post = Post.find(params[:id])

  respond_to do |format|
    if @post.destroy
      format.html { redirect_to posts_url }
      format.json { head :no_content }
    else
      format.html # do something here
      format.json { head :no_content }
    end
  end
end
Kaunas answered 21/10, 2012 at 11:42 Comment(4)
Updated my answer. If this doesn't work either, you should post the server logs.Kaunas
still not working... there are 2 problems with the above link_to code... first the confirm does not show and second i am not sure if the link_to even reaches the destroy action... it simply seems that it goes to the post itself... - edit : also in the dev logs there isny anything weird... it simply does a GETHermelindahermeneutic
Well it shouldn't be doing a get. Can you post your logs? And your routes.rb file?Kaunas
updated question with log on link click and routes... removed format.json but still no luckHermelindahermeneutic
D
0

Make sure that there is no space after the param

def destroy
        @post = Post.find(params[:id])
        @post.destroy
        redirect_to posts_path, :notice => "Your post has been deleted successfully."
end
Dereism answered 23/8, 2013 at 16:39 Comment(0)
C
0

Check the whitespaces.

I checked all the comments here. All the includes were set correctly. But I noticed that deleting articles did not work, while deleting comments would work. After rewriting some code and checking here and there, I found two files that looked identically in the editor, but one version would work and one would not work!

curry-blog/app/views/articles/index.html.erb:

<h1>Listing Articles</h1>
<%= link_to 'New article', new_article_path %>
<table>
  <tr>
    <th>Title</th>
    <th>Text</th>
    <th colspan="3"></th>
  </tr>
 
  <% @articles.each do |article| %>
    <tr>
      <td><%= article.title %></td>
      <td><%= article.text %></td>
      <td><%= link_to 'Show', article_path(article) %></td>
      <td><%= link_to 'Edit', edit_article_path(article) %></td>
      <td><%= link_to 'Delete', article_path(article),
              method: :delete,
              data: { confirm: 'Are you sure?' } %></td>        
    </tr>
  <% end %>
</table>

However, looking at the files with xxdiff I found that in one version only tabs where used, while the other also used blanks. Probably, from copy pasting code from the tutorial. Replacing the blanks with tabs did therefore fix the problem.

Commemorative answered 3/10, 2016 at 12:33 Comment(0)
T
-1

it's working perfectly for me, <%= button_to 'Delete', article_path(article), method: :delete %>

Therewith answered 7/5, 2022 at 19:6 Comment(1)
OP asks specifically about the link_to methodColbert

© 2022 - 2024 — McMap. All rights reserved.