15

within my RoR project my delete method is not working. It's weird because it was working a day ago but now all it does it redirects me to the "friend" page. Another thing to note is that the pop up dialog of "are you sure?" also does not show up when deleting a friend when it was working previously. I read some solutions online stating to put "//= require jquery" and "//= require jquery_ujs" in your javascript file but all I could find was my manifest.js file in my "app/assets/config" directory.

Any help would be greatly appreciated.

index.html.erb

<% if user_signed_in? %>
  <table class="table table-striped table-bordered table-hover">
    <thead class="thead-dark">
      <tr>
        <th>Name</th>
        <th>Email</th>
        <th>Phone</th>
        <th>Twitter</th>
        <th>User ID</th>
        <th></th>
      </tr>
    </thead>

    <tbody>
      <% @friends.each do |friend| %>
        <% if friend.user == current_user %>
          <tr>
            <td>
            <%= link_to friend.first_name + " " + friend.last_name, friend, style: 'text-decoration:none' %>
            </td>
            <td><%= friend.email %></td>
            <td><%= friend.phone %></td>
            <td><%= friend.twitter %></td>
            <td><%= friend.user_id %></td>
            <td>
              <%= link_to 'delete', 
              friend,
              :method => :delete,
              :confirm => "are you sure?", 
              class: "btn btn-danger btn-sm" %>
            </td>
          </tr>
        <% end %>
      <% end %>
      
    </tbody>
  </table>

  <br>

<% else %>
  <h1>Welcome to the Friend App</h1>
<% end %>

manifest.js

//= link_tree ../images
//= link_tree ../builds
//= require jquery
//= require jquery_ujs
0

9 Answers 9

21

In Rails 7 the "old" way of specifying the delete method does not work. My guess is the change from rails-ujs to turbo is the culprit. Rails-ujs was moved into Rails as of version 5.1 and Hotwire Turbo replaces it in rails 7.

This is how I solved my problem:

route: destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy

.html.erb:

<%= link_to t('navigation.sign_out'), destroy_user_session_path, method: :delete, class: "btn btn-danger ml-3" %>

html: (notice the data-method="delete")

<a class="btn btn-danger ml-3" rel="nofollow" data-method="delete" href="/users/sign_out"><span class="translation_missing" title="translation missing: en.navigation.sign_out">Sign Out</span></a>

Error: No route matches [GET] "/users/sign_out"

Solved it with (solution source)

.html.erb:

<%= link_to t('navigation.sign_out'), destroy_user_session_path, data: { "turbo-method": :delete }, class: "btn btn-danger ml-3" %>

.html: (notice the data-turbo-method="delete")

<a data-turbo-method="delete" class="btn btn-danger ml-3" href="/users/sign_out"><span class="translation_missing" title="translation missing: en.navigation.sign_out">Sign Out</span></a>
Sign up to request clarification or add additional context in comments.

6 Comments

Thank you! This did the trick for me. I was also wondering if there's any way to implement js.erb files into Ruby on Rails 7 with ESBuild and import maps?
Can anyone explain what "t('navigation.signout')" does? Thank you.
@ClintLaskowski: it fetches the right localized string for 'navigation.signout'. guides.rubyonrails.org/i18n.html
So when we upgrade from older rails versions we have to replace every "method: :delete" with data: { "turbo-method": :delete }? I am unhappy about this. Now I have to replace so many things and I can't search and replace, because I already use the data field for different other things...
This change is documented in the official Working with JavaScript in Rails guide
|
13

Just a quick note for rails 7 if you want the confirmation message to work out of the box:

<%= link_to t('navigation.sign_out'),
  destroy_user_session_path,
  data: { turbo_method: :delete, turbo_confirm: 'Are you sure?' },
  class: "btn btn-danger ml-3" %>

Comments

7

Rails 7 uses Turbo and stimulus framework to increase frontend performance.

You need to install turbo and stimulus. Run below commands on your terminal:

$ rails importmap:install 
$ rails turbo:install stimulus:install

Make sure you are using turbo_method like:

<%= link_to "Sign Out", destroy_user_session_path, data: { turbo_method: :delete }, class: "nav-link" %>

Comments

2

I upgraded my app to Rails 7 but didn't want to use import maps, turbo etc. so I came up with my own Javascript solution for adding a confirmation dialogue to my destroy links.

First of all I turned all my links into buttons which makes it a lot easier to trigger a delete request:

def link_to_destroy(object)
  path = send("#{controller_name.singularize}_url", object)
  button_to "Destroy", path, :method => :delete, :data => { :confirm => "Are you sure?" }, :form_class => "confirm_destroy", :class => "destroy_icon"
end

(Note that Rails will automatically wrap those buttons in a form tag with a delete method included. I found styling those buttons surprisingly easy. I had to change only one line of code in my CSS.)

This is the Javascript I am using to trigger the confirmation dialogue:

function ConfirmDestroy() {

  const forms = document.querySelectorAll('.confirm_destroy');

  forms.forEach(form => {
    form.addEventListener('submit', function(e) {
      handleSubmit(form, e);
    });
  });

  function handleSubmit(form, e) {
    e.preventDefault();
    let message = form.querySelector('button').dataset.confirm; // pull the actual confirmation message from the data-attribute 'confirm' to support multiple languages
    if (!confirm(message)) {
      return false;
    }
    form.submit();
  }

}

document.addEventListener('DOMContentLoaded', ConfirmDestroy);

I have tested it in the latest versions of Chrome, Safari and Firefox on Mac and haven't encountered any issues so far.


The good thing about this solution is that it also supports multiple languages. The actual confirmation message will simply get pulled from the confirm data attribute. So you can put there any string or message that you want.

1 Comment

Exactly what I need. I just had to update the JavaScript part with an else clause to avoid the form submission without confirmation part. I don't know why the confirmation alert didn't showned up in my case (Rails 8, Ubuntu 20.04, Firefox 136.0).
1

You need to go to section 7.5 of the https://guides.rubyonrails.org/getting_started.html. It explains why

we need to set the data-turbo-method and data-turbo-confirm HTML attributes of the "Destroy" link.

Read the entire section 7.5, including the destroy action in both examples. Also preserve log in your console and observe the errors when you click on Delete button. To avoid head slapping moments, in destroy action try to add status to redirect_to as per rails guides redirect_to whatever_path, status: :see_other this also applies to when you delete an object and render new, you need to set status :unprocessable_entity which leads to server response to 422.

the key here is to ensure you have turbo_method: :delete in your link_to for Turbo, then, method: :delete to change GET to delete, and finally your destroy action to have a status when you're using redirect_to in-order to avoid errors when/if browser redirects you to another location with DELETE method.

<%= link_to "Delete", friend, method: :delete, data: { turbo_method: :delete, turbo_confirm: 'Are you sure?' }, class: 'btn btn-danger' %>

2 Comments

Your answer could be improved by adding more information on what the code does and how it helps the OP.
You're right, I edited my answer, and added as much information as I could. I hope this helps some people.
0

You can use button_to also instead of link_to

<%= button_to friend_path(friend), method: :delete do %>
  Delete
<% end %>

Comments

0

For those who still having problems with this, here are some other steps that could help:

Rails version: 7.0.3.1

Reference: Rails 7: link_to method: :delete not working

follow next steps:

  • bundle add hotwire-rails
  • add gem importmap-rails
  • install importmap rails importmap:install
  • install hotwire rails hotwire:install

and next code works:

%td= link_to t('common.destroy'), task, data: { turbo_method: :delete, turbo_confirm: t('common.confirm') }

as additional info, using:

  • gem hamlit
  • gem simple_form

Comments

0

I was having the same problem and I am mystified. I tried everything but kept failing to destroy and the logs always showed the page rendering as HTML and not as turbo stream. I then switched to the Opera browser (from chrome) and everything worked as expected. make any sense?

1 Comment

Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
-1

You need to pass the path for the controller, not just the object.

<%= link_to 'delete', 
          friend_path(friend),
          :method => :delete,
          :confirm => "are you sure?", 
          class: "btn btn-danger btn-sm" %>

You also need to find the correct path for this request, you could do the following to find the matching routes for friend.

rails routes | grep friend

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.