ruby on rails 3 - links - Método link_to de Rails: GETing cuando debería DELETE
rails link_to params (6)
Estoy siguiendo el Tutorial Rails de Michael Hartl y, por alguna razón, el siguiente código:
<%= link_to ''delete'', user, :method => :delete, :confirm => "You sure?",
:title => "Delete #{user.name}" %>
Emite una solicitud GET (como lo verifiqué revisando el registro del servidor de rieles). También verifiqué que la siguiente línea se encuentra en la vista de mi aplicación:
<%= javascript_include_tag :all %>
Una cosa que no entendí del todo, y probablemente sea la fuente de mi problema: ¿dónde se define el método "eliminar"? Verifiqué en el código fuente de Hartl que define un método de "destrucción" en el controlador, no "eliminar". Pero incluso si cambio el link_to a: method =>: destroy, solo emite un GET.
Estoy usando Rails 3.1. ¿Algun consejo?
Como los navegadores no admiten el verbo DELETE , Rails crea una solución para este problema simulando una solicitud DELETE través de un GET o POST estándar. El method: :delete forma method: :delete trabajos es con un controlador de JavaScript para todos los enlaces con data-method="delete" que modifica la solicitud para que Rails lo procese como un DELETE . Este manejador JavaScript es proporcionado por la biblioteca jquery_ujs .
Hay varias cosas que podrían haber salido mal:
- Asegúrese de tener ambos
jqueryyjquery_ujscargados en suapplication.jsya que sin ambos nada procesará el enlace. - Asegúrese de que el enlace en cuestión realmente tenga el
method: :deleteopción demethod: :deleteespecificada. - Asegúrese de que, por algún motivo, no haya detenido la propagación del enlace en cuestión, como por ejemplo:
$( ''a'' ).click( function( event ) {
event.stopPropagation()
})
Como esto evitaría que los manejadores jquery_ujs se ejecuten y la solicitud nunca se modificará y seguirá siendo solo un GET estándar.
En los rieles 5:
Tengo el mismo problema, todas las publicaciones de ''DELETE'' se vieron comprometidas, lo que afectó mis páginas de crud Y diseñé el inicio de sesión ... para resolver el problema, todo lo que tenía que hacer era:
// = require rails-ujs
En realidad, debes usar el siguiente código
<%= button_to "delete", @user_current, :method => "delete" %>
Resolverá el problema o agregará esta línea // = requiere jquery_ujs a application.js y usa:
<%= link_to ''delete'', user, :method => :delete, data: {:confirm => "You sure?" } ,
:title => "Delete #{user.name}" %>
La mayoría de los navegadores no son compatibles con el verbo DELETE, por lo que Rails lo falsifica modificando el HTML que genera. Rails tachuelas en un atributo HTML5 llamado data-method y lo establece en "delete" . Por lo tanto, cuando un usuario hace clic en el enlace, en realidad se emite como una solicitud GET , pero el atributo de data-method permite algunos Rallies mágicos y significa que su código de enrutamiento debe reconocerlo como una solicitud DELETE.
editar:
Puedes probarlo tú mismo en la consola. Ejecute bundle exec rails c para acceder a la consola y observe el código HTML que esto genera:
helper.link_to "delete", "foobar/delete", :method => ''delete''
El HTML debería verse así:
<a href="foobar/delete" data-method="delete" rel="nofollow">delete</a>
Me enfrenté al mismo problema con el tutorial de Michael. El data-method="delete" realidad funciona como se esperaba - llama a la acción destruir en el controlador. La razón por la que trata de GET (y finalmente falla) es la siguiente:
Notará que uno de los before_filter del controlador está configurado para signed_in_user , y en session_helper.rb , notará que signed_in_user llama a store_location (método privado), que actualiza la session[:return_to] a la URL actual.
Entonces, de vuelta en la acción de destrucción de tu controlador, intenta redirect_back_or que da como resultado GET current_url . signed_in_user helper signed_in_user para que solo llame a store_location cuando el usuario no haya store_location .
También verifique que esto esté en su application.js:
//= require jquery
//= require jquery_ujs
Aparentemente tenía el jquery sin jquery_ujs y tuve el mismo problema hasta que agregué eso.