Метод link_to Rails: ПОЛУЧЕНИЕ, когда следует УДАЛИТЬ

Я следую Rails Tutorial Майкла Хартла и по какой-то причине следующий код:

<%= link_to 'delete', user, :method => :delete, :confirm => "You sure?",
                                :title => "Delete #{user.name}" %>

Выдает запрос GET (как я убедился, проверив журнал сервера rails). Я также подтвердил, что в моем представлении приложения есть следующая строка:

<%= javascript_include_tag :all %>

Я не совсем понял одну вещь, и это, вероятно, источник моей проблемы: где определен метод «удаления»? Я проверил в исходном коде Хартла, что он определяет метод «уничтожения» в контроллер, а не "удалить". Но даже если я изменю link_to на: method =>: destroy, он просто выдаст GET.

Я использую Rails 3.1. Какие-нибудь советы?


person koggit    schedule 19.09.2011    source источник


Ответы (7)


Большинство браузеров на самом деле не поддерживают команду 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>
person jergason    schedule 19.09.2011
comment
Спасибо, Джергасон! Это HTML-код, который Rails генерирует для моего удаления - ‹a href = / users / 1 data-confirm = Вы уверены? data-method = delete rel = nofollow title = Удалить Джаред Клемент ›delete ‹/a› - все выглядит нормально, но когда я нажимаю эту ссылку, не удаляется. Я использую Chrome и обычно не имею проблем с Javascript. Есть идеи, где я могу найти проблему? - person koggit; 19.09.2011
comment
Как выглядит ваш routes.rb файл? - person jergason; 19.09.2011
comment
Мой здесь: github.com/koggit/global2local-interpret/ blob / master / config / Hartl находится здесь: github. com / railstutorial / sample_app / blob / master / config / По сравнению с этим все выглядит нормально, хотя я еще не очень хорошо понимаю маршруты. - person koggit; 19.09.2011
comment
Можете ли вы определить, срабатывает ли ваш метод UsersController # destroy при нажатии этой ссылки? Воткнуть линию печати или что-то в этом роде? - person jergason; 19.09.2011
comment
Спасибо за вашу постоянную помощь, Джергасон. UserControler # destroy не запускается. Возможно, я обнаружил проблему: Served asset /all.js - 404 Not Found. Он пытается ПОЛУЧИТЬ /assets/all.js, которого не существует. Я искал информацию об этом файле в Google, но ничего не нашел. Какие-нибудь советы по поисковым запросам, чтобы узнать больше о all.js в этом контексте? - person koggit; 20.09.2011
comment
Похоже, что материал Rails UJS не включен. Если вы используете Rails 3.1, возможно, у вас происходят какие-то странности с вашим конвейером ресурсов. Я не слишком знаком с этим, но вы должны убедиться, что ваши активы компилируются правильно. Вы можете попробовать изменить тег include на javascript_include_tag :defaults, чтобы узнать, поможет ли это. - person jergason; 20.09.2011
comment
Спасибо - ваш ответ помог мне найти ключевые слова для поиска этого сообщения, в котором есть решение - stackoverflow.com/questions/7281907/ - к сожалению, несмотря на работу, это неясно что касается почему этого решения. Ну что ж. :) Спасибо еще раз! - person koggit; 20.09.2011
comment
Решение button_to, приведенное ниже, было для меня лучшим решением! - person Jesse Smith; 15.02.2021

Также убедитесь, что это находится в вашем application.js:

//= require jquery
//= require jquery_ujs 

По-видимому, у меня был jquery без jquery_ujs, и у меня была такая же проблема, пока я не добавил это.

person Jamel Toms    schedule 27.12.2013

Вы должны использовать следующий код

<%= button_to "delete", @user_current, :method => "delete" %>

Это решит проблему или добавит эту строку // = require jquery_ujs в application.js и будет использовать:

 <%= link_to 'delete', user, :method => :delete, data: {:confirm => "You sure?" } ,
                            :title => "Delete #{user.name}" %>
person Hien Luong    schedule 13.02.2015
comment
Если вы не хотите включать JQuery, я считаю, что переключение link_tobutton_to устранит эту проблему. - person adarsh; 14.06.2016
comment
Я согласен. Если вы хотите использовать link_to, добавьте jquery_ujs в application.js - person Hien Luong; 31.03.2017

Я столкнулся с той же проблемой с учебником Майкла. data-method="delete" на самом деле работает так, как ожидалось - он вызывает действие уничтожения в контроллере. Причина, по которой он пытается 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 только тогда, когда пользователь еще не вошел в систему.

person Brij    schedule 06.04.2012

Поскольку браузеры не поддерживают команду DELETE, Rails создает обходной путь для этой проблемы, моделируя DELETE запрос через стандартные GET или POST. method: :delete работает с обработчиком JavaScript для всех ссылок с data-method="delete", который изменяет запрос, поэтому Rails обрабатывает его как DELETE. Этот обработчик JavaScript предоставляется библиотекой jquery_ujs.

Есть несколько вещей, которые могли пойти не так:

  1. Убедитесь, что в вашем application.js включены и jquery, и jquery_ujs. Без того и другого ничто не будет обрабатывать атрибуты данных.
  2. Убедитесь, что в рассматриваемой ссылке действительно указан параметр method: :delete.
  3. Убедитесь, что по какой-то причине вы не остановили распространение события для рассматриваемой ссылки, например, так:
$( 'a' ).click( function( event ) {
    event.stopPropagation()
})

Поскольку это предотвратит выполнение обработчиков jquery_ujs, и запрос никогда не будет изменен и останется стандартным GET.

person Itay Grudev    schedule 20.09.2017

По рельсам 5:

У меня та же проблема, все сообщения «УДАЛИТЬ» были скомпрометированы, что повлияло на мои грубые страницы И разработать выход ... для решения проблемы все, что мне нужно было сделать, это:

// = требуется rails-ujs

person DribeiroExp    schedule 19.07.2018

Все, что нам нужно, это добавить следующую строку кода

//= require jquery_ujs 

Вроде баг :))

person giapnh    schedule 18.10.2019