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

Posted

技术标签:

【中文标题】没有路线匹配 [GET] "/users/sign_out"【英文标题】:No route matches [GET] "/users/sign_out" 【发布时间】:2011-09-27 21:55:09 【问题描述】:

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

我正在使用 devise 1.4.2 和 Rails 3.1.0.rc4。此外,我还生成了两个独立的设计模型——一个称为“成员”,另一个称为“管理员”。通过手动导航到正确的 URL 路径(即 localhost:3000/admins/sign_in/),我能够(同时)注册和登录它们。我按照RailsCast on Devise 在我的 application.html.haml 布局文件中创建了一些链接。我知道它只处理“会员”的登录/注销链接。

如果我点击退出链接,我会收到上述错误。如果我手动导航到任一注销 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"

routes.rb

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

  devise_for :admins

  resources :films

  root :to => 'films#index'
end

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

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

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

【问题讨论】:

我遇到了与 OP 对 /users/sign_out 相同的错误,因为我正在获取它而不是删除它(我也是第一年的开发人员)。通过此答案检查 github 后,我提交了拉取请求以更正它! github.com/plataformatec/devise/pull/2040 去 S.O. !!! 【参考方案1】:

我遇到了类似的问题,但添加 :method=> :delete 不起作用。 通过注释掉 devise_for :users 并添加

,我能够为 get 请求添加新路由
devise_for :users do
  get '/users/sign_out' => 'devise/sessions#destroy'
end

【讨论】:

在尝试了一大堆解决方案来解决看似很常见的问题后,这是唯一真正有效的解决方案。 这可能有效,但它不遵循 CRUD。使用下面的答案,使用正确的方法。 = link_to "Sign out", destroy_user_session_path,:method => :delete 你会写更少的代码。 :method => :delete 解决方案应该有效,但对我也不起作用。 API 文档中有关 :delete 的一些 cmets 表明这可能是一个 JS 问题......但是上面的这个解决方案(重定向 GET)效果很好。 在尝试此操作之前,请阅读下面的 Victor Martins 答案 无需打破宁静的路线。如果由于某种原因您的应用程序不使用标准 Rails js,则使用 button_to 方法,其 attrs 与 link_to 相同。它将生成一个包含单个按钮的表单,并且不会尝试使用任何 js :)【参考方案2】:

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

# The default HTTP method used to sign out a resource. Default is :delete.
config.sign_out_via = :get

只需打开链接,您的会话就会被删除。

【讨论】:

+1 为你解决这个问题的正确方法。这在 ./config/initializers/devise.rb 中。 这看起来不像推荐的方式,因为它隐藏了一些其他问题。请参阅 Jose Valim 对此问题的评论:github.com/plataformatec/devise/issues/1351 在我收到此错误的应用程序中,发现在我包含 Twitter Bootstrap 后 JQuery 没有正确链接。更正 app/assets/javascripts/application.js 中的 jquery 设置解决了问题。 似乎语法应该是:config.sign_out_via_get_becuase_of = :ie 我遇到了同样的问题。普拉卡什是对的。这是一个JS问题。删除链接也停止工作。【参考方案3】:

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

destroy_member_session DELETE /members/sign_out(.:format)      :action=>"destroy", :controller=>"devise/sessions"

这意味着该路由仅适用于 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 

【讨论】:

我在他们的 github 存储库中发布了一个问题,他们给了我相同的修复方法。如果你通过 :delete %> 它将起作用。 将路由作为 DELETE 路由与将其更改为 GET 路由有优缺点吗? ***.com/questions/4573305/… 是该问题的一个不错的答案。我不知道使用 DELETE 路由是否有很多缺点,但这是首选方式。【参考方案4】:

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

  <%= link_to " exit", destroy_user_session_path, method: :delete %>

将以下更改添加到 routes.rb 后,它起作用了,

devise_for :users

devise_scope :user do  
   get '/users/sign_out' => 'devise/sessions#destroy'     
end

【讨论】:

【参考方案5】:

我只需要添加

//= require jquery
//= require jquery_ujs

致我的application.js

【讨论】:

我错过了 //= require jquery_ujs,它实际上使 link_to 函数中的 method: :delete 参数起作用。干得好:) 魔鬼在细节中:P 这对我有用。出于某种原因,来自 RailsWizard.com 的 rails 4 模板应用程序甚至没有 application.jsapplication.css,更不用说这些行了。我不明白//= 部分。这是评论吗? //= 是资产管道工作方式的一部分。它看起来像是 javascript 的注释行,但实际上它是由 rails 执行以加载某些内容的行。 在我的例子中是//= require rails-ujs工作【参考方案6】:

在devise.rb中,改变

 config.sign_out_via = :delete

config.sign_out_via = :get

这对我有用。我疯了,因为默认是delete,我不明白为什么。

这可行,但我不确定它是否会影响应用程序中的其他元素。

【讨论】:

【参考方案7】:

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

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

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

= javascript_include_tag "application" (haml- you can use html too)

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

【讨论】:

【参考方案8】:
= link_to "Sign out", destroy_user_session_path,:method => :delete

工作,而不是使用这个,

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

应该在你的 application.js

中添加 require jquery_ujs

【讨论】:

【参考方案9】:

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

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

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

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

如docs所见

【讨论】:

有机会看到你的答案,你在 10 分钟前写了它 :) 非常感谢它解决了我的问题【参考方案10】:

使用 Rails4,我不得不使用以下方法:

<%= link_to "Logout", destroy_admin_session_path, method: :delete %>

强调冒号在 method: 和 :delete 上的位置

【讨论】:

【参考方案11】:

也许这会对某人有所帮助。 从 Rails 3.0 升级到 3.1 发现了这个问题。 这为我修复了它:

routes.rb: devise_for: 用户

设计.rb: config.sign_out_via = :delete

application.html.erb:

<%= javascript_include_tag "application" %>     

* 不是:默认值

_login_items.html.erb:

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

app/assets/javascripts/application.js

//= require jquery
//= require jquery-ui
//= require jquery_ujs
//= require_tree .

我在 javascript/jquery.js、jquery_ujs.js 中从 3.0 版本中删除。

【讨论】:

【参考方案12】:

您可能已经删除了 assets/javascripts/*

运行rails generate jquery:install --ui这将生成所有的javascript,如下所示

xxxx@xxxxx:~/Projects/Rails_apps/rtest$ rails generate jquery:install --ui
      remove  public/javascripts/prototype.js
      remove  public/javascripts/effects.js
      remove  public/javascripts/dragdrop.js
      remove  public/javascripts/controls.js
     copying  jQuery (1.7.1)
      create  public/javascripts/jquery.js
      create  public/javascripts/jquery.min.js
     copying  jQuery UI (1.8.16)
      create  public/javascripts/jquery-ui.js
      create  public/javascripts/jquery-ui.min.js
     copying  jQuery UJS adapter (822920)
      remove  public/javascripts/rails.js
      create  public/javascripts/jquery_ujs.js

转到您的布局,例如 application.html.erb 并编辑 &lt;%= javascript_include_tag :all %&gt;

这对我有用:)

【讨论】:

【参考方案13】:

FWIW 我也遇到过这个问题。已经查看了所有建议的答案,但唯一有效的是打开 routes.rb 并注释掉以下行:

devise_for :users

在其下方,添加以下行:

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

【讨论】:

【参考方案14】:

问题始于assets/javascript/ 中的rails 3.1。只需查找application.js,如果该文件不存在,则创建一个具有该名称的文件。我不知道为什么我的文件消失或从未在 rails new app 上创建过……该文件是 jquery 的实例。

【讨论】:

【参考方案15】:

@creamhost 说,

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

但这对我来说不是正确的解决方案(Rails4)。我解决了我们的问题(@Olives 的回答),

link_to :logout, destroy_member_session_path, method: :delete

【讨论】:

这不是一个答案,它应该是一个评论,因为你要低代表发表评论,标记一个模组以将其更改为评论。【参考方案16】:

我使用的是 Rails 版本 5。我也遇到了这个问题。我所做的简单修复是将设计配置更改为初始化为默认值。

发件人:

config.sign_out_via = :get

收件人:

config.sign_out_via = :delete

【讨论】:

【参考方案17】:

只需使用以下链接作为您的退出链接:

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

【讨论】:

【参考方案18】:
//= require jquery_ujs

您的资产中缺少这一行。无需获取/users/signout 请求。将此行放入页面最顶部的 JavaScript 文件中。

【讨论】:

【参考方案19】:

遇到了同样的问题,并记得它只是在我决定“清理”我的 Javascript 文件后才开始发生的。所以我再次运行rails generate jquery:install --ui,这为我解决了这个问题。 (我想,如果你不需要 JQuery UI,你可以忽略 --ui 部分。)

【讨论】:

【参考方案20】:

使用正确的 HTTP 方法保留您的 devise.rb

# good 
config.sign_out_via = :delete

# bad
config.sign_out_via = :get

使用button_to 而不是link_to

# good 
= button_to "Sign Out", destroy_user_session_path, method: :delete

# bad
= link_to "Sign Out", destroy_user_session_path, method: :delete"

如果您使用的是引导程序(保持优雅)

= link_to "Sign Out", destroy_user_session_path, method: :delete, class: "btn btn-default btn-sm"

参考:github.com/heartcombo/devise/issues/4570#issuecomment-740812109

【讨论】:

【参考方案21】:

它只发生在 Windows 上。将以下内容添加到您的 Application.html.erb 文件中。

devise_for :users

设计范围:用户做 获取 '/users/sign_out' => '设计/会话#destroy' 结束

【讨论】:

以上是关于没有路线匹配 [GET] "/users/sign_out"的主要内容,如果未能解决你的问题,请参考以下文章

没有路线匹配 [GET] "/users/sign_out" **Rails 5/Bootstrap 4**

Rails 3.2.13 - 没有路线匹配 [GET] "/js/jquery.fancybox.js"

带有设计的 Rails 3:没有路线匹配 /d/users/sign_out

Rails 3.0.9 + Devise + Cucumber + Capybara 臭名昭著的“没有路线匹配 /users/sign_out”

路由错误克隆目录后没有路由匹配 [GET] "/logout"

没有路线匹配 [GET] /assets