Не найдено ни одного маршрута «/ users / sign_out» devise rails 3

368

Я установил приложение для своего приложения и применил следующее в моем файле application.html.erb:

<div id="user_nav">
    <% if user_signed_in? %>
        Signed in as <%= current_user.email %>. This cannot be cheese?
        <%= link_to 'Sign out', destroy_user_session_path %>
    <% else %>
        <%= link_to 'Register', new_user_registration_path %> or <%= link_to 'Sign in', new_user_session_path %>
    <% end %>
</div>

Я запустил rake routes и подтвердил, что все маршруты действительны.

Кроме того, в моем routes.rb файле есть devise_for :users и root :to => "home#index".

При нажатии ссылки "Выйти" я получаю следующую ошибку маршрутизации:

No route matches "/users/sign_out"

Любые идеи, которые вызывают ошибку?

  • 1
    Вы перезапустили свое приложение после добавления маршрутов? Изменения маршрута вступают в силу только при запуске.
  • 2
    Да. Просто сделал это снова, чтобы быть в безопасности. Кроме того, я читал где-то еще в Stack, что это может быть проблемой из-за того, что новейший гем devise не совместим с Rails 3.0.3, поэтому я попытался изменить свой гем devise с 1.4.2 на gem 'devise', :git => 'git://github.com/plataformatec/devise.git' . Это ничего не сделал, хотя.
Показать ещё 7 комментариев
Теги:
routes
devise
ruby-on-rails-3

29 ответов

576
Лучший ответ

Я думаю, что маршрут для выхода - это метод DELETE. Это означает, что ваша ссылка на выход должна выглядеть так:

<%= link_to "Sign out", destroy_user_session_path, :method => :delete %>

В ваш раздел не входит :method => :delete. Также обратите внимание, что для этого вы также должны включить <%= javascript_include_tag :defaults %> в свой файл макета (application.html.erb).

  • 3
    Я могу с уверенностью сказать, что мне никогда не приходилось делать это ни в одном из моих Rails-приложений. link_to "Sign out", destroy_user_session_path всегда был достаточно хорош для меня.
  • 8
    Я сделал тест, и он работает для меня. Не забывайте, что вещи меняются от одной версии к другой (будь то в Rails или Devise). Кроме того, выход из системы - это поведение, изменяющее состояние, которое не должно выполняться методами GET (по моему скромному мнению).
Показать ещё 10 комментариев
132

Я изменил эту строку в devise.rb:

config.sign_out_via = :delete

к

config.sign_out_via = :get

и он начал работать для меня.

  • 0
    Это было бы как сделать это, если вы не хотите добавлять собственный путь или использовать удаление
  • 22
    Чтобы сделать это раньше, нужно было выйти, используя «GET / users / sign_out», но они изменили его на «DELETE», чтобы сделать его более RESTful. Автор объяснил, что GET не должен вносить изменения в сервер, такие как выход из системы.
Показать ещё 6 комментариев
59

Вероятно, вы не включили javascript файл jquery_ujs. Убедитесь, что вы используете последнюю версию jquery-ujs: https://github.com/rails/jquery-ujs и последние доступные файлы:

rails generate jquery:install

У вас не должно быть больше файла rails.js. Если вы это сделаете, вы, вероятно, устарели. Убедитесь, что этот файл загружен по умолчанию, в config/application.rb

config.action_view.javascript_expansions[:defaults] = %w(jquery.min jquery_ujs)

(Опять же, у вас не должно быть файла rails.js). Наконец, добавьте ссылку, как описано на Разработать wiki (haml-style):

= link_to('Logout', destroy_user_session_path, :method => 'delete')

И все будет хорошо.

  • 8
    У меня было: method => 'delete' в моей ссылке, проблема была в том, что jquery_ujs не был включен, это решение решило мою проблему. Не забудьте поместить гем 'jquery-rails' в ваш гемфайл.
  • 1
    ты гений, и я хотел бы +10 этот пост ...
Показать ещё 5 комментариев
29

Возможность сделать ссылку "Выйти" вызовом DELETE RESTful требует атрибута html data-method = "delete" с помощью кода rails = link_to('Logout', destroy_user_session_path, :method => :delete).

Однако, если у вас нет установленного gem jquery-ujs или не вызывается результирующий javascript в вашем приложении application.html через = javascript_include_tag "application", ответ будет отправлен как запрос GET, и маршрут не будет выполнен.

У вас есть несколько вариантов, если вы не хотите использовать jquery-ujs или не можете найти способ заставить его работать:

  • Измените config.sign_out_via равным :get в пределах devise.rb (не рекомендуется, поскольку DELETE - соответствующий запрос RESTful)
  • ИЛИ Измените link_to на = button_to('Logout', destroy_user_session_path, :method => :delete). С помощью button_to Rails сделает тяжелый подъем при правильном вызове DELETE. Затем вы можете навести кнопку, чтобы выглядеть как ссылка, если хотите.
  • 0
    Переход от link_to к button_to сработал для меня, но я действительно не понимаю, почему? Что именно изменилось, кроме HTML / CSS?
  • 1
    Это связано с «магией» рельсов, которая автоматически генерирует html из таких функций, как button_to и link_to. Просто так получилось, что магия рельсов для button_to указывает правильный вызов RESTful DELETE, а link_to - нет. Если бы мне пришлось угадывать, я бы сказал, что причина в том, что элементы HTML-кнопки могут обрабатывать вызов DELETE (или связывать со скрытым полем, определяющим действие), в то время как обычные ссылки не могут.
Показать ещё 3 комментария
25

Попробуйте добавить новый маршрут для создания/сеансов # destroy и ссылки на него. Например:

routes.rb
devise_for :users do
  get 'logout' => 'devise/sessions#destroy'
end

Вид:

<%= link_to "Logout", logout_path %>
  • 0
    Получаю ту же ошибку, что и Микаэль. Этот тест выше работает для меня.
  • 1
    У меня тоже была та же ошибка, что и у Майкла. Решение выше будет работать, но это не так, как это должно быть исправлено. Маршруты по умолчанию в Devise уже включают маршрут выхода из системы как метод DELETE. Обычно вам не нужно менять маршруты по умолчанию. Вот почему вы можете это исправить, просто добавив отдельный параметр в вызов link_to , как описано в другом ответе.
Показать ещё 7 комментариев
13

Используйте его в файле routes.rb:

devise_for :users do
    get '/users/sign_out' => 'devise/sessions#destroy'
end
  • 0
    лучший ответ на данный момент
12

У меня была та же проблема с rails 3.1.0, и я решил добавить в файл следующие строки:

app/assets/javascripts/application.js
//= require_tree
//= require jquery
//= require jquery_ujs
  • 0
    В моем случае добавление jquery_ujs решило проблему!
  • 0
    Если вы используете bower, попробуйте // = require jquery-ujs.
Показать ещё 1 комментарий
10

За одним исключением, ответ Джесси работал у меня:

<%= link_to "Sign out", destroy_user_session_path, :method => :delete %>

изменения:

:delete

... to:

'delete'

Итак, код, который работал у меня:

<%= link_to "Sign out", destroy_user_session_path, :method => 'delete' %>
  • 0
    Спасибо за публикацию этого фрагмента кода, у меня работает sign_out.
  • 0
    Лучший ответ на данный момент
8

Многие ответы на вопрос уже есть. Для меня проблема была в два раза:

  • когда я расширяю маршруты:

    devise_for :users do 
       get '/users/sign_out' => 'devise/sessions#destroy'
    end
    
  • Я предупреждал, что это обесценивается, поэтому я заменил его на:

    devise_scope :users do
       get '/users/sign_out' => 'devise/sessions#destroy'
    end
    
  • Я думал, что удалю свой jQuery. Плохой выбор. Devise использует jQuery для "подделки" запроса DELETE и отправляет его как GET. Поэтому вам необходимо:

    //= require jquery
    //= require jquery_ujs
    
  • и, конечно, та же самая ссылка, о которой говорилось выше:

    <%= link_to "Sign out", destroy_user_session_path, :method => :delete %>
    
  • 0
    Можете ли вы объяснить 3-й пункт .. Я был жертвой этого, и я хочу понять это больше
  • 1
    Конечно. Ваш веб-сайт на самом деле не отправляет запросы на УДАЛЕНИЕ. Откровенно говоря, он будет использовать только GET и POST. Потому что в сообществе Rails было решено, что (по уважительным причинам) мы хотим удалять записи при отправке запроса DELETE, нам нужно использовать небольшую хитрость. Когда в вашем ERB вы указываете метод:: delete rails преобразует это в тег HTML5: data-method = "delete" и отправляет его как GET. Теперь вот где jQuery-ujs и jQuery включаются. Они позволяют приложению распознавать, что вы делаете. Так что ваш запрос может быть сопоставлен с действием контроллера.
Показать ещё 1 комментарий
7

Добавить

  <%= csrf_meta_tag %>  and 
  <%= javascript_include_tag :defaults %>  to layouts

Используйте эти теги link_to

 link_to 'Sign out', destroy_user_session_path, :method => :delete

  or

 link_to 'Sign out', '/users/sign_out', :method => :delete

В маршрутах добавьте:

  devise_for :users do
    get '/users/sign_out' => 'devise/sessions#destroy'
  end
6

Если вы используете Rails 3.1, убедитесь, что ваш значок application.html.erb выглядит так:

<%= link_to "Sign out", destroy_user_session_path, :method => :delete %>

И что ваша строка с поддержкой javascript выглядит следующим образом

<%= javascript_include_tag 'application' %>

Я предполагаю, что некоторые драгоценные камни перезаписывают новую структуру местоположения default.js.

  • 0
    Спасибо! Это сводило меня с ума!
6

Другой вариант - настроить выход из системы как GET вместо DELETE, вы можете сделать это, добавив следующую строку в /config/initializers/devise.rb

config.sign_out_via = :get

Но так как Стив Клабник написал в своем блоге (http://blog.steveklabnik.com/2011/12/11/devise-actioncontroller-routingerror-no-route-matches-get-slash-sers-slash-sign- out.html) попытайтесь использовать DELETE из-за семантики этого метода.

  • 0
    Только этот ответ работал для меня для Devise 3.5.1 и Rails 4.2.3
  • 0
    Не забудьте перезагрузить сервер :)
5

Это означает, что вы не сгенерировали файлы jquery после установки jquery-rails gem. Поэтому сначала вам нужно сгенерировать его.

rails generate devise:install

Первый вариант:

Это означает, что вам нужно изменить следующую строку на /config/initializers/devise.rb

config.sign_out_via =: удалить в config.sign_out_via =: get

Второй вариант:

Вы только изменяете эту строку <%= link_to "Sign out", destroy_user_session_path %> на <%= link_to "Sign out", destroy_user_session_path, :method => :delete %> в файле вида.

Обычно :method => :delete не записывается по умолчанию.

  • 1
    THX Deepak ...... это также работает для меня :)
5

Я хочу добавить к этому, даже если он немного стар.

ссылка "sign_out" не работает, несмотря на наличие метода: method = > : delete.

Комментарий, указывающий, что <%= javascript_include_tag :defaults %> должен быть включен, напомнил мне, что я недавно добавил JQuery java script и использовал простые теги <script src=""/> для их включения.

Когда я переместил их из следующих значений: по умолчанию до этого, sign_out снова начал работать.

Надеюсь, это поможет кому-то.

5

Ну, ребята, для меня это только удалил: method = > : delete

<%= link_to('Sign out', destroy_user_session_path) %>
5

Проверьте это с исходным кодом в github:

https://github.com/plataformatec/devise/commit/adb127bb3e3b334cba903db2c21710e8c41c2b40#lib/generators/templates/devise.rb (дата: 27 июня 2011 г.)

  • # Метод HTTP по умолчанию, используемый для выделения ресурса. По умолчанию: get. 188
  • # config.sign_out_via =: get 187
  • # Метод HTTP по умолчанию, используемый для выделения ресурса. По умолчанию: delete. 188
  • config.sign_out_via =: удалить
4

Не забудьте включить следующую строку в ваш application.js(Rails 3)

//= require_self
//= require jquery
//= require jquery_ujs

Включите jquery_ujs в мое приложение rails и теперь оно работает.

3

Если вы используете HTTPS с приложением, он будет разорван, если ваша ссылка на выход будет в незащищенной версии. На задней панели он перенаправляется на защищенную версию. Это перенаправление - это GET, что вызывает проблему.

Убедитесь, что ваша ссылка использует HTTPS. Вы можете заставить его с помощью protocol: "https" в вашем помощнике URL (убедитесь, что вы используете помощник URL, а не помощник пути).

<%= link_to "Sign out", destroy_user_session_url(protocol: "https"), method: :delete %>
3

Большинство ответов являются частичными. Я много раз сталкивался с этой проблемой. Необходимо решить две вещи:

<%= link_to(t('logout'), destroy_user_session_path, :method => :delete) %>

необходимо указать метод удаления

Затем devise использует jquery, поэтому вам нужно загрузить эти

   <%= javascript_include_tag "myDirectiveJSfile" %> 

и убедитесь, что BOTH jQuery и jquery-ujs указаны в вашем myDirectiveJSfile.js

//= require jquery
//= require jquery_ujs
2

используйте метод :get и :delete для вашего пути:

devise_scope :user do
  match '/users/sign_out' => 'devise/sessions#destroy', :as => :destroy_user_session, via: [:get, :delete]
end
  • 0
    Примечание: должен быть devise_for: пользователи, объявленные отдельно от этого. смотрите ответ от dipole_moment.
2

Здесь много решений. но в основном используйте это,

<%= link_to 'Sign out', destroy_user_session_path, method: :delete %>

или config devise.rb с правильным методом sign_out

В devise.rb

config.sign_out_via = :delete ( or  :get which u like to use.) 
2

':method => :delete 'на странице: data-method="delete"' поэтому ваша страница должна иметь jquery_ujs.js, она отправит ссылку с методом delete not method get

2

В ваших route.rb:

 devise_for :users do
    get '/sign_out' => 'devise/sessions#destroy'
    get '/log_in' => 'devise/sessions#new'
    get '/log_out' => 'devise/sessions#destroy'
    get '/sign_up' => 'devise/registrations#new'
    get '/edit_profile' => 'devise/registrations#edit'
 end

и в вашем приложении application.html.erb:

<%if user_signed_in?%>
          <li><%= link_to "Sign_out", sign_out_path %></li>
<% end %>
  • 0
    Синтаксис теперь такой: devise_for: users, тогда значения должны быть помещены в devise_scope: user do ПРИМЕЧАНИЕ: singular: user для devise_scope
2

Проблема начинается с рельсов 3.1... в /app/assets/javascript/ просто найдите application.js.

Если файл не существует, создайте файл с таким именем, я не знаю, почему мой файл исчез или никогда не был создан на "rails new app"....

Этот файл является экземпляром для jquery....

2

Это то, что я сделал (с Rails 3.0 и Devise 1.4.2):

  • Убедитесь, что ваша страница загружает rails.js
  • Используйте этот параметр: 'data-method' = > 'delete'
  • Хорошая идея добавить этот параметр:: rel= > 'nofollow'
1
  devise_for :users
  devise_scope :user do
    get '/users/sign_out' => 'devise/sessions#destroy'
  end
1

В общем случае, когда вы получаете "Нет совпадений в маршруте", но вы считаете, что этот маршрут определен, тогда дважды проверьте метод http-глагола/запроса (будь то его получение, put, post, delete и т.д.) для этого маршрута.

Если вы запускаете маршруты рейка, вы увидите ожидаемый метод, и вы можете сравнить его с журналом запросов.

1

Посмотрите, есть ли у вашего route.rb "ресурс: пользователи" перед "devise_for: users", затем попробуйте их заменить:

  • Работы

    • devise_for: users
    • ресурсы: пользователи
  • Не удается

    • ресурсы: пользователи
    • devise_for: users
0

Я знаю, что это старый вопрос, основанный на Rails 3, но я просто столкнулся с ним и решил его на Rails 4.0.4. Поэтому я подумал, что смогу понять, как я исправил его для тех, кто сталкивается с этой проблемой с этой версией. Ваш пробег может измениться, но вот что сработало для меня.

Сначала убедитесь, что у вас установлены камни и запущена установка пакета.

gem 'jquery-rails'

gem 'turbolinks'

gem 'jquery-turbolinks'

В application.js убедитесь, что все требуется, как показано ниже.

Остерегайтесь, если это gotcha: it //= require jquery.turbolinks, а не //= require jquery-turbolinks

//= require jquery
//= require jquery_ujs
//= require jquery.turbolinks
//= require turbolinks
//= require_tree .

Затем добавьте соответствующие ссылки в заголовок application.html.erb.

<%= javascript_include_tag  "application", "data-turbolinks-track" => true %>
<%= javascript_include_tag :defaults %>

Кажется, что существует много вариантов того, как реализовать метод delete, который, как я полагаю, зависит от версии Rails, которую вы используете. Это синтаксис delete, который я использовал.

<p><%= link_to "Sign Out", destroy_user_session_path, :method => 'delete' %></p>

Надеюсь, что поможет выкопать кого-то из этой очень расстраивающей дыры!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню