Rails 'link_to метод: GETing, когда он должен УДАЛИТЬ
Я следую руководству Michael Hartl Rails и по какой-то причине следующий код:
<%= link_to 'delete', user, :method => :delete, :confirm => "You sure?",
:title => "Delete #{user.name}" %>
Выдает запрос GET (как я проверял, проверяя журнал сервера rails). Я также подтвердил, что следующая строка находится в представлении моего приложения:
<%= javascript_include_tag :all %>
Одна вещь, которую я не совсем понял, и это, вероятно, источник моей проблемы: где определяется метод удаления? Я подтвердил в исходном коде Hartl, что он определяет метод "destroy" в контроллере, а не "delete". Но даже если я изменил link_to на: method = > : destroy, он просто выдает GET.
Я использую Rails 3.1. Любые советы?
Ответы
Ответ 1
Большинство браузеров фактически не поддерживают глагол DELETE, поэтому Rails подделывает его, изменяя созданный HTML-код. Rails привязывается к атрибуту HTML5 с именем data-method
и устанавливает его в "delete"
. Поэтому, когда пользователь нажимает на ссылку, она фактически выдается как запрос GET
, но атрибут data-method
позволяет использовать некоторую магию Rails и означает, что ваш код маршрутизации должен распознавать его как запрос DELETE.
изменить
Вы можете протестировать его самостоятельно в консоли. Запустите bundle exec rails c
, чтобы войти в консоль, и посмотрите на HTML, который это генерирует:
helper.link_to "delete", "foobar/delete", :method => 'delete'
HTML должен выглядеть следующим образом:
<a href="foobar/delete" data-method="delete" rel="nofollow">delete</a>
Ответ 2
Также проверьте, что это находится в вашем приложении application.js:
//= require jquery
//= require jquery_ujs
По-видимому, у меня был jquery без jquery_ujs, и у меня была такая же проблема, пока я не добавил это.
Ответ 3
Собственно, вы должны использовать следующий код
<%= button_to "delete", @user_current, :method => "delete" %>
Он разрешит проблему или добавит эту строку // = потребует jquery_ujs к application.js и использует:
<%= link_to 'delete', user, :method => :delete, data: {:confirm => "You sure?" } ,
:title => "Delete #{user.name}" %>
Ответ 4
Я столкнулся с той же проблемой с учебником Майкла. data-method="delete"
работает как и ожидалось - он вызывает действие destroy в контроллере. Причина, по которой он пытается выполнить GET
(и, в конечном счете, не работает), выглядит следующим образом:
Вы заметите, что один из before_filter
в контроллере установлен в signed_in_user
, а в session_helper.rb
вы заметите, что signed_in_user
вызывает store_location
(частный метод), который обновляет session[:return_to]
к текущему URL.
Итак, снова в вашем контроллере уничтожить действие, он пытается redirect_back_or
, что приводит к GET current_url
. Я изменил помощник signed_in_user
только для вызова store_location
, когда пользователь уже не подписал.
Ответ 5
Поскольку браузеры не поддерживают глагол DELETE
, Rails создает обходной путь для этой проблемы путем моделирования запроса DELETE
через стандартный GET
или POST
. Способ method: :delete
работает с обработчиком JavaScript для всех ссылок с data-method="delete"
, который изменяет запрос так, чтобы Rails
обрабатывает его как DELETE. Этот обработчик JavaScript предоставляется библиотекой jquery_ujs
.
Есть несколько вещей, которые могли бы пойти не так:
- Удостоверьтесь, что у вас есть как
jquery
, так и jquery_ujs
, загруженные в вас application.js
, так как без них ничего не обработает ссылка.
- Убедитесь, что соответствующая ссылка действительно имеет указанную опцию
method: :delete
.
- Убедитесь, что по какой-то причине вы не остановили распространение события соответствующей ссылки, например, так:
$( 'a' ).click( function( event ) {
event.stopPropagation()
})
Так как это предотвратит выполнение обработчиков jquery_ujs
, и запрос никогда не будет изменен и останется только стандартным GET.
Ответ 6
На рельсах 5:
Возникла та же проблема, все посты 'УДАЛИТЬ' были скомпрометированы, что повлияло на мои грубые страницы И разработало выход... чтобы решить проблему, все, что мне нужно было сделать, это:
//= требовать rails-ujs
Ответ 7
Все, что нам нужно, это добавить следующую строку кода
//= require jquery_ujs
Это похоже на ошибку :))