Rails 7 - link_to with method :delete still performs GET request - ruby-on-rails

I am trying to get this link to work, performing a DELETE request:
<%= link_to "Sign Out", destroy_user_session_path, method: :delete %>
However when I click on it, my browser still performs a GET request (which fails for obvious reasons):
I have read on multiple other forum posts, that this might have something to do with jquery not being included. They mentioned you would need to un-comment a line in app/javascript/application.js, however mine is pretty empty:
// Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails
import "#hotwired/turbo-rails"
import "controllers"
These forum posts were also quite old, so I suspect something has changed in the meantime.

As suggested here, the following will suffice:
<%= link_to "Sign Out", destroy_user_session_path, data: { "turbo-method": :delete } %>
I have tested this in my project and it seems to work fine. Thanks also to #alexts, you basically figured this out too, however the comment on GitHub even eliminated the double-request.

There are (at least) two ways to delete something in rails 7:
Using button_to (preferred IMHO):
<%= button_to 'Sign Out', destroy_user_session_path, method: :delete %>
Renders an HTML form which sends a POST request with a hidden _method attribute with 'delete' value. Rails will treat this as if it has a DELETE method (and route it to products#destroy or whatever your routes are saying). Do not use this one within another form (HTML forbids one form inside another).
Using link_to:
<%= link_to 'Sign Out', destroy_user_session_path, data: {turbo_method: :delete} %>
Renders a simple a tag with data-turbo-method attribute. This link sends a real DELETE request.
If your destroy action ends with a redirect_to, some browsers will redirect to a new location with DELETE method (causing errors), so make sure to add status: :see_other parameter to redirect_to, like the guides suggest.
Confirmation
If you want to add confirmation prompt to a button above:
<%= button_to 'Sign Out', destroy_user_session_path, method: :delete,
form: {data: {turbo_confirm: 'Are you sure?'}} %>
If you want to add confirmation to a link above:
<%= link_to 'Sign Out', destroy_user_session_path,
data: {turbo_method: :delete, turbo_confirm: 'Are you sure?'} %>

Found it on git
Run these commands
It worked for me.
$ rails importmap:install
$ rails turbo:install stimulus:install

method: :delete just add a attribute
in order to make it useful, rails_ujs library is responsible
try to include it
that can be useful

Related

Rails: How do I delete a row from database? [duplicate]

I am trying to get this link to work, performing a DELETE request:
<%= link_to "Sign Out", destroy_user_session_path, method: :delete %>
However when I click on it, my browser still performs a GET request (which fails for obvious reasons):
I have read on multiple other forum posts, that this might have something to do with jquery not being included. They mentioned you would need to un-comment a line in app/javascript/application.js, however mine is pretty empty:
// Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails
import "#hotwired/turbo-rails"
import "controllers"
These forum posts were also quite old, so I suspect something has changed in the meantime.
As suggested here, the following will suffice:
<%= link_to "Sign Out", destroy_user_session_path, data: { "turbo-method": :delete } %>
I have tested this in my project and it seems to work fine. Thanks also to #alexts, you basically figured this out too, however the comment on GitHub even eliminated the double-request.
There are (at least) two ways to delete something in rails 7:
Using button_to (preferred IMHO):
<%= button_to 'Sign Out', destroy_user_session_path, method: :delete %>
Renders an HTML form which sends a POST request with a hidden _method attribute with 'delete' value. Rails will treat this as if it has a DELETE method (and route it to products#destroy or whatever your routes are saying). Do not use this one within another form (HTML forbids one form inside another).
Using link_to:
<%= link_to 'Sign Out', destroy_user_session_path, data: {turbo_method: :delete} %>
Renders a simple a tag with data-turbo-method attribute. This link sends a real DELETE request.
If your destroy action ends with a redirect_to, some browsers will redirect to a new location with DELETE method (causing errors), so make sure to add status: :see_other parameter to redirect_to, like the guides suggest.
Confirmation
If you want to add confirmation prompt to a button above:
<%= button_to 'Sign Out', destroy_user_session_path, method: :delete,
form: {data: {turbo_confirm: 'Are you sure?'}} %>
If you want to add confirmation to a link above:
<%= link_to 'Sign Out', destroy_user_session_path,
data: {turbo_method: :delete, turbo_confirm: 'Are you sure?'} %>
Found it on git
Run these commands
It worked for me.
$ rails importmap:install
$ rails turbo:install stimulus:install
method: :delete just add a attribute
in order to make it useful, rails_ujs library is responsible
try to include it
that can be useful

How do I add a confirm message to a logout prompt in Ruby on Rails?

I have attempted to use the following code to add a confirmation message to a logout option in a dropdown menu, but it's not working.
<%= link_to "Logout", destroy_user_session_path, method: :delete, data: {confirm: 'Are you sure?'}, class: "dropdown-item" %>
I feel like I either made a random misspelling or I'm missing something glaringly obvious. Thanks in advance!

The difference between delete and the other routes

Below I have the link-helpers for the actions edit and destroy. The first link (and all the others) is working perfectly but the second creates a weird url that doesn't work.
<%= link_to "Edit", edit_event_path(organizer_vanity_url: event.organizer.vanity_url, id: event.id) %>
<%= link_to 'Remove', event_path(organizer_vanity_url: event.organizer.vanity_url, id: event.id), method: :delete, data: { confirm: 'Are you sure?' } %>
This is from the routes.rb:
scope "organizer" do
scope ":organizer_vanity_url" do
scope "manage" do
resources :events
end
end
end
What is the difference between the delete link-helper and the others (as that's the only one that doesn't work)?
link_to - is GET-request-like helper (by default)
DELETE method is POST-like method
so, you passing post method to get helper and receive "weird url"
to solve this you have two options:
use button_to instead of link_to helper (first one is for post form submitting, by default)
use js to correctly handle your link.

:confirm in rails not working

I just started coding in ruby on rails and I've been following a guide which is using a more outdated version of rails than I am using. I am using 3.2.12
This is my code:
<%= button_to 'Destroy', product, :method => "delete", :confirm => 'Are you sure?' %>
From what I understand, these are symbols that are passed to rails, which is then converted to either an html or javascript action that then pops up the message box and deletes the object if applicable. The above code destroys the object, but it does not pop up the confirm box. Why is this? Also, I had the above as the following at first:
<%= link_to 'Destroy', product, :method => "delete", :confirm => 'Are you sure?' %>
The confirm box is not popping up under any circumstance, using link_to or button_to. Below is the html rendered when inspected using Chrome's inspector. jquery and jquery-ujs are loaded into the as well, so I'm not sure where to go from here.
<input name="_method" type="hidden" value="delete">
<input data-confirm="Are you sureeee?" type="submit" value="Destroy">
<input name="authenticity_token" type="hidden" value="Q2xicqELHYHtrwarbtPBe5PT2bZgWV5C+JdcReJI8ig=">
Thanks!
I had to add my confirm attribute inside the data attribute to get it to work. I am using rails 4 with bootstrap. I hope this helps someone else who has that issue.
link_to 'Delete', #rule, method: :delete, data: { confirm: 'Are you sure you want to delete this alert?' }
This relies on jQuery, ensure you have the following:
in your Gemfile
group :assets do
gem 'jquery-rails'
end
in your assets/javascripts/application.js file, before the line //= require_tree .
//= require jquery
//= require jquery_ujs
The difference between link_to and button_to is the HTTP verb. link_to issues GET requests and button_to issues POST requests. With the RESTful routing, the delete action is a POST request to controller/id. If you issue a GET to controller/id, it is dispatched to the show action.
AIUI, link_to with anything other than the GET verb is a Bad Idea. One, right-clicks don't preserve the verb. Two, you don't want bots crawling the page to follow the link and thereby trigger the delete action even though you probably need to be logged in to actually modify the database.
Feel pretty dumb, but adblock was blocking the message box. Sorry about that. All is well now, I just disabled adblock.
If you want to delete something with confirmation box in rails 7, you may try this one:
With button_to (more prefered IMHO):
<%= button_to 'Destroy', product, method: :delete,
form: {data: {turbo_confirm: 'Are you sure?'}} %>
This will render an HTML form tag which sends a POST request on submit (after confirmation) but with a hidden _method attribute with 'delete' value. So that rails will treat this request as if it has a DELETE method.
It will be routed to products#destroy (or whatever your routes are saying).
With link_to:
<%= link_to 'Destroy', product,
data: {turbo_method: :delete, turbo_confirm: 'Sure?'} %>
This will render a simple a tag with data-turbo-method and data-turbo-confirm attributes. Clicking this link will trigger a confirmation box and if "OK" is chosed, a real DELETE request will be sent.
If you want to end destroy action in your controller with a redirect_to, some browsers will redirect to a new location with DELETE method (causing errors), so make sure to add status: :see_other parameter, like the guides suggests.
I have a pop-up blocker running in Chrome. I just whitelisted http://localhost:3000 and it worked for me.

Button_to in Ruby on Rails bad route

I'm trying to use the button_to rails helper. I wrote the following code:
<%= button_to 'Edit Item', edit_item_path(#item), :class => 'mark-button' %>
and got the following error message
No route matches "/items/1/edit"
But when I refresh the page it goes to the appropriate action. The URL of the page i get is localhost:3000/items/1/edit which is the correct URL. If I switch the button_to command to link_to the page loaded with no errors. Meaning this code:
<%= link_to 'Edit Item', edit_item_path(#item), :class => 'mark-button' %>
loads fine. Maybe there is some feature of button_to I'm not aware of, but I am at a lost.
I think you might be misusing button_to. I've always thought that if you're linking to the edit action, you should be using link_to. Buttons seem to be for actions that need to post/put data such as updating a form or deleting a record.
Update:
By default, button_to uses POST instead of GET. Hence it working when you just visit the URL (ie GET).
button_to defaults to POST, and link_to defaults to GET.
If you really need button_to you can change the default method to GET for edit and other links.
for ex:
<%= button_to 'Edit', edit_user_path(#user), :method => :get %>
Ruby -v 2.8.6, Rails 6.1.4.1
<%= button_to 'Edit', edit_item_path(item), :method => :get %> because with expression (#item) you do not define the object you want to edit, because (#item) it is not a specific object, there are several and you need to define only the one you want to edit, :method => :get this method is perfect

Resources