Devise: Почему моя выходная ссылка не работает?
Проблема: в двух словах, когда я пытаюсь установить ссылку для выхода в мое приложение, она не работает. Здесь так много контекста, как я могу подумать, чтобы поместить здесь (если вы хотите что-нибудь еще, пожалуйста, соберите меня)...
У меня это в представлении haml:
= link_to("Logout", destroy_user_session_path, :method => :delete)
Он генерирует это в представлении:
<a href="/users/sign_out" data-method="delete" rel="nofollow">Logout</a>
Я подтвердил, что в моем config/initializers/devise.rb у меня этот параметр раскоментирован и исправлен:
config.sign_out_via = :delete
Я проверил следующий маршрут:
destroy_user_session DELETE /users/sign_out(.:format) {:action=>"destroy", :controller=>"devise/sessions"}
У меня также есть этот обман в моих маршрутах .rb, и я подозреваю, что это связано с моей проблемой:
devise_for :users, :controllers => {:sessions => "devise/sessions", :registrations => "users"}
resources :users
Этот последний бит - это то, что я хочу управлять (редактировать, создавать и удалять) пользователей в моем собственном контроллере.
Сообщение об ошибке, которое я получаю, выглядит следующим образом:
ActiveRecord::RecordNotFound in UsersController#show
Couldn't find User with ID=sign_out
Rails.root: /home/jaydel/projects/mbsquared-projects/Wilson-Goldrick
app/controllers/users_controller.rb:16:in `show'
В моих журналах сервера я вижу это для запроса:
Started GET "/users/sign_out" for 127.0.0.1 at 2011-08-04 13:08:51 -0500
Processing by UsersController#show as HTML
Parameters: {"id"=>"sign_out"}
У кого-нибудь есть идеи?
Ответы
Ответ 1
Проблема заключается в том, что в ваших журналах запрос на отправку является запросом GET.
Started GET "/users/sign_out"
Но маршрут выведения - DELETE
destroy_user_session DELETE /users/sign_out(.:format)
Причина, по которой вы получаете исключение, заключается в том, что она путается с одним из маршрутов, созданных resources :users
, что было бы похоже на
edit_user GET /users/(:id)(.:format) {:action=>"edit", :controller=>"users"}
В основном "sign_out" ошибочно принимается как идентификатор.
Я не уверен, почему ссылка удаления не проходит в качестве запроса DELETE. Хотя изменение
config.sign_out_via = :delete
будет :get
может решить проблему.
Ответ 2
Правильный способ исправить это, REST-мудрый, будет заключаться в том, чтобы изменить ссылки на выход, чтобы использовать метод DELETE. Это очень легко исправить, изменив это:
link_to "Log out", destroy_user_session_path
:
link_to "Log out", destroy_user_session_path, :method => :delete
Ответ 3
У меня была та же проблема с рельсами 3.2, когда я удалил из application.js
эту строку:
//= require jquery_ujs
Итак, я думаю, вы должны вставить эту строку в свой application.js
, если у вас ее нет.
PS. Это означает, что адаптер рельсов для jquery
не работает. Поэтому вы должны убедиться, что он загружен в ваш html в браузере. Вы должны проверить его в режиме разработки, потому что у вас будет сжатый js в производстве, и там будет очень сложно что-то найти.
Ответ 4
Это старый вопрос, но принятый ответ - не правильный способ решить эту проблему (хотя это хороший диагноз проблемы).
Когда я столкнулся с этим, мой файл маршрутов появился как:
root :to => 'welcome#index'
resources :users
devise_for :users
Как упоминалось Оливами, выражение о ресурсах просто вызывает/пользователей/что-то, что можно было бы отключить. Мне просто нужно было отменить порядок моих маршрутов...
root :to => 'welcome#index'
devise_for :users
resources :users
Ответ 5
jQuery требуется для выполнения запроса с помощью DELETE. Убедитесь, что вы не уронили его из приложения application.js.
Ответ 6
Вам нужны оба
link_to "Log out", destroy_user_session_path, method: :delete
& & они включены в application.js
//= require jquery
//= require jquery_ujs
. Очевидно, не забудьте добавить это в Gemfile, если по какой-то причине его там нет.
gem 'jquery-rails'
Ответ 7
Это старый вопрос, но мне нужен способ, который не требовал JavaScript. Rails позволяет "УДАЛИТЬ" как запросы со скрытым входом, который устанавливает method
в delete
. Используйте реальный <form>
, и пусть Rails генерируют необходимые скрытые входы:
<%= form_for(resource, as: resource_name,
url: destroy_user_session_path, html: { method: :delete }) do |f| %>
<%= f.submit "Log out" %>
<% end %>
приведенное выше генерирует что-то вроде:
<form accept-charset="UTF-8" action="/users/sign_out" method="post">
<div style="display:none">
<input name="utf8" type="hidden" value="✓">
<input name="_method" type="hidden" value="delete">
<input name="authenticity_token" type="hidden" value="1234">
</div>
<input name="commit" type="submit" value="Log out">
</form>
Ответ 8
Мне пришлось обходиться по-другому, так как мое приложение application.rb:
<%= link_to "Sign out", destroy_user_session_path, :method => :delete %>
и все еще не удалось. Оказывается, мне нужно установить config.serve_static_assets = true
в /environment/development, test и production.rb. Эта ссылка помогла мне разобраться.
Ответ 9
Вам также нужно проверить, есть resources :users
в разделе devise_for :users
и метод ссылки удаляет
link_to "Logout", destroy_user_session_path, method: :delete
если оба правильные, ваша кнопка выхода из системы должна работать
Ответ 10
Я проверил все эти решения, но никто не работал на меня. Наконец, я обнаружил, что в заголовке я удалил две строки, включая теги приложений и csrf metap >
Итак, если у кого-то есть эта проблема без разрешения в этот момент - проверьте, есть ли у вас в заголовке страницы (нотация HAML)
= javascript_include_tag 'application'
= csrf_meta_tags
Ответ 11
Поскольку упомянутый OP был разработан, и эта проблема также произошла со мной, я просто хотел прослушивать. @Ross Allen получил правильный ответ, когда вы не хотите использовать jQuery_ujs. Rails предоставляет пару помощников для решения этой проблемы без jQuery.
Это ответ Росса, но с использованием модели Devise current_user:
<%= form_for(current_user,
url: destroy_user_session_path, html: { method: :delete }) do |f| %>
<%= f.submit "Log out" %>
<% end %>
Или более сжатый button_to помощник, который создает аналогичную форму:
<%= button_to "Log out", destroy_user_session_path, method: :delete %>
Ответ 12
Я согласен с тем, что более удобно использовать метод http DELETE, мне нравится создавать простую конечную точку для уничтожения сеанса пользователя с помощью метода GET.
добавив это в config/routes.rb
devise_scope :user do
get '/logout', :to => 'sessions#destroy'
end
Ответ 13
Если у вас также есть несколько источников jquery в вашем приложении rails, вам нужно использовать значение по умолчанию, указанное в Gemfile
убедитесь, что в вашем Gemfile у вас есть этот
gem 'jquery-rails'
и в ваших активах у вас нет других исходных файлов JQuery.
в моем случае у меня был второй файл JQuery, отличный от значения по умолчанию, как указано в Gemfile, поэтому он вызвал конфликты.
если вы ранее имели этот источник, не забудьте предварительно скомпилировать активы, если вы ранее делали это
Ответ 14
Если вы обнаружили эту проблему в производстве и используете конвейер активов, вам часто необходимо:
rake assets:clobber
, чтобы очистить ваши публичные активы. Затем rake assets:precompile
перед совершением и нажатием вашего кода (если только ваш push также не прекомпилирует, ака Heroku).
Ответ 15
причина может быть в неправильном порядке соединения bootstrap-sprockets
правильный порядок:
// app/assets/javascripts/application.js
...
//= require jquery
//= require jquery_ujs
//= require turbolinks
//= require bootstrap-sprockets
//= require_tree .
Ответ 16
Как уже упоминалось Tombart, ответ для меня заключался в том, чтобы вернуть вызов rails-ujs в файл application.js.
//= require rails-ujs
//= require turbolinks
Я изначально удалил их, чтобы остановить ошибки из-за переоценки моих сценариев в нижнем колонтитуле. Моим обходным решением было создать файл footer.js для компиляции с ресурсами, которые я хотел бы в нижнем колонтитуле.
//= require jquery-3.2.1.min
//= require jquery-ui-1.12.1.min
//= require materialize
//= require init
Затем в файле /initializers/assets.rb добавляется прекомпиляция
Rails.application.config.assets.precompile += %w( footer.js )
Затем вы можете вызвать следующее в файле layout/application.html.erb.
<%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
<%= javascript_include_tag 'footer' %>
Я сохраняю строку приложения в своем заголовке и добавляю свой новый вызов "нижнего колонтитула" до конца тега body.