没有路线匹配[GET]"/ users/sign_out"

Joe*_*Joe 26 authentication devise ruby-on-rails-3.1

这是我的实际错误:No route matches [GET] "/members/sign_out" 由于大多数人会使用"用户",我认为在标题中使用它会更有帮助.无论如何,我必须无法注销.我可以成功编辑我的会员资料.

我正在使用设计1.4.2和Rails 3.1.0.rc4.此外,我已经生成了两个独立的设计模型 - 一个称为"成员",另一个称为"管理员".我能够通过手动导航到正确的URL路径(即localhost:3000/admins/sign_in /)来注册并登录它们(同时).我在我的application.html.haml布局文件中创建了一些链接,方法是在Devise上使用这个RailsCast.我知道它只涉及"成员"的登录/注销链接.

如果我点击退出链接,我会收到上述错误.如果我手动导航到任何一个注销URL(即localhost:3000/admins/sign_out /),就会发生这种情况.

有人能告诉我为什么会这样吗?以下是各种相关文件.当然,我是新手......

rake路线输出:

    j(film_repo)$ rake routes
        new_member_session GET    /members/sign_in(.:format)       {:action=>"new", :controller=>"devise/sessions"}
            member_session POST   /members/sign_in(.:format)       {:action=>"create", :controller=>"devise/sessions"}
    destroy_member_session DELETE /members/sign_out(.:format)      {:action=>"destroy", :controller=>"devise/sessions"}
           member_password POST   /members/password(.:format)      {:action=>"create", :controller=>"devise/passwords"}
       new_member_password GET    /members/password/new(.:format)  {:action=>"new", :controller=>"devise/passwords"}
      edit_member_password GET    /members/password/edit(.:format) {:action=>"edit", :controller=>"devise/passwords"}
                           PUT    /members/password(.:format)      {:action=>"update", :controller=>"devise/passwords"}
cancel_member_registration GET    /members/cancel(.:format)        {:action=>"cancel", :controller=>"devise/registrations"}
       member_registration POST   /members(.:format)               {:action=>"create", :controller=>"devise/registrations"}
   new_member_registration GET    /members/sign_up(.:format)       {:action=>"new", :controller=>"devise/registrations"}
  edit_member_registration GET    /members/edit(.:format)          {:action=>"edit", :controller=>"devise/registrations"}
                           PUT    /members(.:format)               {:action=>"update", :controller=>"devise/registrations"}
                           DELETE /members(.:format)               {:action=>"destroy", :controller=>"devise/registrations"}
         new_admin_session GET    /admins/sign_in(.:format)        {:action=>"new", :controller=>"devise/sessions"}
             admin_session POST   /admins/sign_in(.:format)        {:action=>"create", :controller=>"devise/sessions"}
     destroy_admin_session DELETE /admins/sign_out(.:format)       {:action=>"destroy", :controller=>"devise/sessions"}
            admin_password POST   /admins/password(.:format)       {:action=>"create", :controller=>"devise/passwords"}
        new_admin_password GET    /admins/password/new(.:format)   {:action=>"new", :controller=>"devise/passwords"}
       edit_admin_password GET    /admins/password/edit(.:format)  {:action=>"edit", :controller=>"devise/passwords"}
                           PUT    /admins/password(.:format)       {:action=>"update", :controller=>"devise/passwords"}
 cancel_admin_registration GET    /admins/cancel(.:format)         {:action=>"cancel", :controller=>"devise/registrations"}
        admin_registration POST   /admins(.:format)                {:action=>"create", :controller=>"devise/registrations"}
    new_admin_registration GET    /admins/sign_up(.:format)        {:action=>"new", :controller=>"devise/registrations"}
   edit_admin_registration GET    /admins/edit(.:format)           {:action=>"edit", :controller=>"devise/registrations"}
                           PUT    /admins(.:format)                {:action=>"update", :controller=>"devise/registrations"}
                           DELETE /admins(.:format)                {:action=>"destroy", :controller=>"devise/registrations"}
                     films GET    /films(.:format)                 {:action=>"index", :controller=>"films"}
                           POST   /films(.:format)                 {:action=>"create", :controller=>"films"}
                  new_film GET    /films/new(.:format)             {:action=>"new", :controller=>"films"}
                 edit_film GET    /films/:id/edit(.:format)        {:action=>"edit", :controller=>"films"}
                      film GET    /films/:id(.:format)             {:action=>"show", :controller=>"films"}
                           PUT    /films/:id(.:format)             {:action=>"update", :controller=>"films"}
                           DELETE /films/:id(.:format)             {:action=>"destroy", :controller=>"films"}
                      root        /                                {:controller=>"films", :action=>"index"}
Run Code Online (Sandbox Code Playgroud)

的routes.rb

FilmRepo::Application.routes.draw do
  devise_for :members

  devise_for :admins

  resources :films

  root :to => 'films#index'
end
Run Code Online (Sandbox Code Playgroud)

admin.rb(型号)

class Admin < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :token_authenticatable, :encryptable, :confirmable, :lockable, and :omniauthable
  devise :database_authenticatable, :registerable, :timeoutable,
         :recoverable, :rememberable, :trackable, :validatable

  # Setup accessible (or protected) attributes for your model
  attr_accessible :email, :password, :password_confirmation, :remember_me
end
Run Code Online (Sandbox Code Playgroud)

member.rb(型号)

class Member < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  # Setup accessible (or protected) attributes for your model
  attr_accessible :email, :password, :password_confirmation, :remember_me
end
Run Code Online (Sandbox Code Playgroud)

application.html.haml

!!!
%html
    %head
        %title Film Repo
        = stylesheet_link_tag 'compiled/screen.css', :media => 'screen, projection'
        = stylesheet_link_tag 'compiled/print.css', :media => 'print'
        /[if lt IE 8]
            = stylesheet_link_tag 'compiled/ie.css', :media => 'screen, projection'
            = csrf_meta_tag
    %body.bp
        #container
            #user_nav
                - if member_signed_in?
                    Signed in as #{current_member.email}. Not you?
                    \#{link_to "Sign out", destroy_member_session_path}
                - else
                    = link_to "Sign up", new_member_registration_path
                    or #{link_to "sign in", new_member_session_path}
                - flash.each do |name, msg|
                    = content_tag :div, msg, :id => "flash_#{name}"
            = yield
Run Code Online (Sandbox Code Playgroud)

itk*_*vin 46

您可以通过更改初始化程序中的设备配置来通过get结束会话.

# The default HTTP method used to sign out a resource. Default is :delete.
config.sign_out_via = :get
Run Code Online (Sandbox Code Playgroud)

只需打开链接即可删除会话.

  • +1以正确的方式解决这个问题.这是在./config/initializers/devise.rb中. (6认同)
  • 如果你到目前为止,你可能知道这一点,但确保在进行此更改后重新启动rails服务器(即使在开发中). (3认同)

cra*_*ead 45

我有类似的问题,但添加:method =>:delete不起作用.通过注释掉devise_for:users并添加,我能够为get请求添加新路由

devise_for :users do
  get '/users/sign_out' => 'devise/sessions#destroy'
end
Run Code Online (Sandbox Code Playgroud)

  • 在尝试了大量解决方案之后,这是一个非常常见的问题,这是唯一真正有效的解决方案. (4认同)
  • 这可能有效但不遵循CRUD.使用下面的答案,使用正确的方法.= link_to"退出",destroy_user_session_path,:method =>:delete您将编写更少的代码. (3认同)
  • :method =>:删除解决方案应该工作,但对我来说也不起作用.API文档中有关于:delete的一些注释表明这可能是一个JS问题......但是上面的这个解决方案(重定向GET)工作得很好. (2认同)
  • 无需打破宁静的路线。如果由于某种原因您的应用程序不使用标准的rails js,则使用具有与“link_to”相同属性的“button_to”方法。它将生成一个表单,包含一个按钮,并且不会尝试使用任何 js :) (2认同)

Oli*_*ves 21

虽然我不知道原因,但是你收到该消息的原因是因为你的路线中有

destroy_member_session DELETE /members/sign_out(.:format)      {:action=>"destroy", :controller=>"devise/sessions"}
Run Code Online (Sandbox Code Playgroud)

这意味着该路由仅适用于DELETE方法而不是GET.这有点奇怪,因为在设计文档中它说应该创建它作为GET路由(https://github.com/plataformatec/devise/blob/master/lib/devise/rails/routes.rb#L30)

将它作为DELETE路由,您应该可以使用注销

link_to :logout, destroy_member_session_path, :method => :delete 
Run Code Online (Sandbox Code Playgroud)

  • 我在他们的github repo中发布了一个问题,他们给了我同样的解决方案.如果您传递<%= link_to"Logout",destory_member_session_path,:method =>:delete%>它将起作用. (3认同)

Vic*_*ins 18

我只需要添加

//= require jquery
//= require jquery_ujs
Run Code Online (Sandbox Code Playgroud)

对我的 application.js

  • 我错过了`// = require jquery_ujs`,它实际上使link_to函数中的`method :: delete`参数工作.干得好:) (2认同)

Rez*_*eza 17

我遇到了类似的问题.我的视图代码是这样的:

  <%= link_to " exit", destroy_user_session_path, method: :delete %>
Run Code Online (Sandbox Code Playgroud)

将以下更改添加到routes.rb后,它工作,

devise_for :users

devise_scope :user do  
   get '/users/sign_out' => 'devise/sessions#destroy'     
end
Run Code Online (Sandbox Code Playgroud)


Pau*_*elo 15

如果您出于安全原因想使用:delete方法而不依赖于jquery-ujs您可以使用button_to而不是link_to,例如:

button_to "Log out", destroy_user_session_path, method: :delete

如果使用,link_to您必须确保 JavaScript 处于活动状态:

请注意,如果用户禁用了 JavaScript,请求将回退到使用 GET。

文档中所示


Ahm*_*mza 13

在 Rails 7 中,您需要添加data: { turbo_method: :delete" }link_to. 所以link_to看起来像这样

<%= link_to "Log out", destroy_user_session_path, data: { turbo_method: :delete } %>
Run Code Online (Sandbox Code Playgroud)


duy*_*hoa 6

我们仍然可以:method => :delete在我的代码中使用,就像那样

 = link_to "Sign out", destroy_user_session_path,:method => :delete
Run Code Online (Sandbox Code Playgroud)

我认为我们无法加载包含jquery的javascript的原因,请确保

= javascript_include_tag "application" (haml- you can use html too)
Run Code Online (Sandbox Code Playgroud)

包括jquery-ui和jquery-ujs.因此,如果它仍然出错,我建议将GEMFILE中的rails gem更改为版本3.2.6并调用bundle update更新gems.这个对我有用!


小智 6

在 Rails 6 中:

我刚刚将link_to更改为button_to,并且“退出”正常工作

<%= button_to "Sign out", destroy_user_session_path, method: :delete %>
Run Code Online (Sandbox Code Playgroud)


小智 5

= link_to "Sign out", destroy_user_session_path,:method => :delete
Run Code Online (Sandbox Code Playgroud)

工作,而不是利用这一点,

= link_to "Sign out", destroy_user_session_path,:method => 'delete'
Run Code Online (Sandbox Code Playgroud)

应该做的伎俩或更糟糕的情况在你的application.js中添加需要jquery_ujs


小智 5

在devise.rb中,改变

 config.sign_out_via = :delete
Run Code Online (Sandbox Code Playgroud)

config.sign_out_via = :get
Run Code Online (Sandbox Code Playgroud)

这对我有用.我对此疯狂,因为默认是delete,我不明白为什么.

这有效,但我不确定它是否会影响应用程序中的其他元素.