ChatGPT解决这个技术问题 Extra ChatGPT

没有路线匹配“/users/sign_out”设计rails 3

我已在我的应用上安装了设计,并在我的 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 :usersroot :to => "home#index"

单击“退出”链接时出现以下路由错误:

No route matches "/users/sign_out"

任何想法是什么导致了错误?

添加路线后您是否重新启动了您的应用程序?路由更改仅在启动时生效。
是的。为了安全起见,又做了一次。另外,我在 Stack 的其他地方读到,最新的 devise gem 与 Rails 3.0.3 不兼容可能是一个问题,所以我尝试将我的 devise gem 从 1.4.2 更改为 gem 'devise', :git => 'git://github.com/plataformatec/devise.git'。不过那什么也没做。
更改 Gemfile 中的条目不会让您获得更新版本的设计吗?您是否尝试过指定较低的版本号?
FWIW,如果您的浏览器阻止 javascript,这也可能发生(无法注销),我猜这会阻止 DELETE 操作。我在开始使用 Firefox 的 NoScript 插件后今天遇到了这个问题。
我只是在移动到自定义域后才开始看到这一点。 DELETE 方法在 myapp-staging.herokuapp.com 上运行,但在我移至 myapp.com 后就中断了。使用 GET 有效,但让我觉得有点脏。

K
K M Rakibul Islam

我认为退出的路线是一种 DELETE 方法。这意味着您的退出链接需要如下所示:

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

您的不包括 :method => :delete 部分。此外,请注意,要使其正常工作,您还必须在布局文件 (application.html.erb) 中包含 <%= javascript_include_tag :defaults %>


我可以肯定地说我从来没有在我的任何 Rails 应用程序中这样做过。 link_to "Sign out", destroy_user_session_path 对我来说一直都足够好。
我做了测试,它对我有用。不要忘记事情会从一个版本更改为另一个版本(无论是在 Rails 中还是在 Devise 中)。此外,注销是一种状态改变行为,不应该使用 GET 方法来完成(以我的拙见)。
有关详细信息,请参阅 herehere 说明在最新版本的 Devise 中进行更改的原因。
我遇到了同样的问题,杰西的建议对我有用。我希望任何通过设计 railscast 的人最终都会因为这种变化而结束......
您也可以在您的网络控制台中输入它来测试它$("<a href='/users/sign_out' data-method='delete'>Sign out</a>").appendTo('body'); - 如果页面上加载了 jQuery。
k
kitdesai

我在 devise.rb 中更改了这一行:

config.sign_out_via = :delete

config.sign_out_via = :get

它开始为我工作。


之前的做法是使用“GET /users/sign_out”注销,但他们将其更改为“DELETE”以使其更加 RESTful。作者解释说,GET 不应该对服务器进行更改,例如注销。
这对我有用。虽然我很欣赏这不是最佳做法,但其他答案都失败了。我看不出为什么!!
如果您希望支持多种方法,也可以使用数组。例如:config.sign_out_via = [ :post, :delete ]devise_for :users, :sign_out_via => [ :post, :delete ],如 devise/rails/routes.rb 中所述。
我不会使用 GET 请求注销,因为它会使用户面临 XSRF 攻击。 (黑客创建了一个带有 src="foo.com/users/sign_out" 的图像标签的网站,用户访问它并退出)。
@RyanDoherty Id 我没记错,XSRF 仍然是可能的(攻击者只需在目标 url 上使用带有 action="DELETE" 的表单,然后在页面加载时自动提交)。
D
Drew Stephens

您可能没有包含 jquery_ujs javascript 文件。确保您使用的是最新版本的 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 文件)。最后,添加 Devise wiki 中记录的链接(haml 样式):

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

一切都会好起来的。


我的link_to中有:method =>'delete',问题是不包括jquery_ujs,这个解决方案解决了我的问题。请记住将 gem 'jquery-rails' 放入您的 gemfile 中。
谢谢这对我有用。除了使用默认值,您还可以使用 javascript_include_tag "jquery_ujs"
好收获,谢谢!我正在使用 require.js 异步加载文件并忘记了需要 jquery_ujs。
我假设“u”表示未压缩并从 application.js 中删除了这一行。不好的假设,我想。谢谢。
在将 twitter bootstrap 从 less 更改为 sass 之后,这个问题突然出现了(在我的第 100 个基于设计的应用程序中),我忘记将 //= require jquery_ujs 添加回我的 application.js 中。
W
Will Nathan

使注销链接成为 DELETE RESTful 调用的能力需要使用 rails 代码 = link_to('Logout', destroy_user_session_path, :method => :delete) 的 html 属性 data-method = "delete"

但是,如果您没有安装 gem jquery-ujs 或者没有通过 = javascript_include_tag "application" 在 application.html 中调用生成的 javascript,则响应将作为 GET 请求发送,并且路由将失败。

如果您不想使用 jquery-ujs 或找不到使其工作的方法,您有几个选择:

在 devise.rb 中将 config.sign_out_via 更改为等于 :get(不推荐,因为 DELETE 是适当的 RESTful 查询)或将 link_to 更改为 = button_to('Logout', destroy_user_session_path, :method => :delete)。使用 button_to,Rails 将完成正确的 DELETE 调用。然后,您可以根据需要设置按钮的样式,使其看起来像一个链接。


从 link_to 到 button_to 的更改对我有用,但我真的不明白为什么?除了 html/css 到底发生了什么变化?
它与从 button_to 和 link_to 等函数自动生成 html 的 rails 'magic' 有关。碰巧 button_to 的 rails 魔法指定了正确的 RESTful DELETE 调用,而 link_to 没有。如果我不得不猜测,我会说原因是 html 按钮元素可以处理 DELETE 调用(或与指定操作的隐藏字段捆绑在一起),而常规链接不能。
谢谢你。我将我的应用程序设置为手动处理 jquery,所以我没有 jquery-ujs。使用 bower 或 bundler 安装并包含资产管道的适当行可解决此问题。
关于 button_to,Rails 为整个操作生成一个 form。这就是为什么可以将 :delete 方法与 button_to 一起使用而不是与 link_to 一起使用,只需查看生成的 HTML。
D
Dave Newton

尝试添加一条新路由来设计/会话#destroy 并链接到该路由。例如:

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

看法:

<%= link_to "Logout", logout_path %>

我也有与 mmichael 相同的错误。上面的解决方案会起作用,但这不是应该如何解决的。 Devise 中的默认路由已经包含作为 DELETE 方法的注销路由。您通常不需要自己更改默认路由。这就是为什么您可以通过简单地向 link_to 调用添加一个单独的参数来修复它,如另一个答案中所述。
您不必向 route.rb 文件添加路由,devise 允许您更改 /confit/initializers/ 目录中的 devise.rb 中的方法。
其他任何人都可以确认 Jagira 所说的话。我也正确地找到了这个答案,我正在我的所有项目中实施这个
如果是 routes.rb get '/:lang/user/logout' => 'devise/session#destroy' view <%= link_to "Logout", ??? %>,你如何设置路径?谢谢
现在的语法是:devise_for :users 然后获取必须放在 devise_scope 中:user do 注意:singular :user for devise_scope。请参阅 dipole_moment 的答案。
p
pjumble

在您的 routes.rb 文件中使用它:

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

g
gringo

我在使用 rails 3.1.0 时遇到了同样的问题,我解决了在文件中添加以下行:

app/assets/javascripts/application.js
//= require_tree
//= require jquery
//= require jquery_ujs

如果使用 bower 尝试 //=require jquery-ujs。
J
Jon

除了一个例外,杰西的回答对我有用:

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

改变:

:delete

... 至:

'delete'

所以对我有用的代码是:

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

L
Lukasz Muzyka

这个问题已经有很多答案了。对我来说,问题有两个方面:

当我扩展我的路线时: 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 发送。因此,您需要: //= 需要 jquery //= 需要 jquery_ujs,当然还有与前面提到的许多相同的链接:<%= link_to "Sign out", destroy_user_session_path, :method => :delete %>


当然。您的网站实际上并未发送任何 DELETE 请求。坦率地说,它只会使用 GET 和 POST。因为在 Rails 社区中已经同意(出于充分的理由)我们希望在提交 DELETE 请求时删除记录,所以我们需要使用一个小技巧。在您的 ERB 中指定方法时::delete rails 会将其转换为 HTML5 标记:data-method="delete" 并将其作为 GET 提交。现在,这就是 jQuery-ujs 和 jQuery 发挥作用的地方。它们允许应用程序识别您正在做的事情。以便您的请求可以与控制器操作相匹配。
没有这些宝石,这是行不通的。当然,您可以更改设计的设置(在设计初始化程序中)并要求它使用 GET 而不是 DELETE。
A
Amal Kumar S

添加:

  <%= 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

R
Rodrigo Flores

其他选项是将注销配置为 GET 而不是 DELETE,您可以在 /config/initializers/devise.rb 上添加以下行

config.sign_out_via = :get

但正如 Steve Klabnik 在他的博客 (http://blog.steveklabnik.com/2011/12/11/devise-actioncontroller-routingerror-no-route-matches-get-slash-users-slash-sign-out.html ) 由于此方法的语义,请尝试使用 DELETE。


S
StlTenny

如果您使用的是 Rails 3.1,请确保您的 application.html.erb 注销看起来像:

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

并且您的 javascript 包含行如下所示

<%= javascript_include_tag 'application' %>

我的猜测是某些 gem 会覆盖 default.js 位置的新结构。


S
Shane

用 github 中的源代码检查一下:

https://github.com/plataformatec/devise/commit/adb127bb3e3b334cba903db2c21710e8c41c2b40#lib/generators/templates/devise.rb(日期:2011 年 6 月 27 日)

# 用于注销资源的默认 HTTP 方法。默认为:获取。 188

# config.sign_out_via = :get 187

# 用于注销资源的默认 HTTP 方法。默认为:删除。 188

config.sign_out_via = :delete


w
workdreamer

好吧,对我来说,伙计们只是删除 :method => :delete

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

D
Deepak Lamichhane

这意味着您在安装 jquery-rails gem 后还没有生成 jquery 文件。所以首先你需要生成它。

rails generate devise:install

第一个选项:

这意味着您必须更改 /config/initializers/devise.rb 上的以下行

config.sign_out_via = :delete 到 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


N
NoNaMe

我想补充一点,即使它有点旧了。

“sign_out”链接不起作用,尽管有:method =>:delete。

指示必须包含 <%= javascript_include_tag :defaults %> 的注释提醒我最近添加了 JQuery java 脚本并使用简单的 <script src=""/> 标记来包含它们。

当我将它们从 :defaults 之后移到之前时,sign_out 再次开始工作。

希望这可以帮助某人。


J
Jerome

大多数答案都是片面的。我已经多次遇到这个问题。需要解决两件事:

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

需要指定删除方法

然后设计使用jquery,所以你需要加载那些

   <%= javascript_include_tag "myDirectiveJSfile" %> 

并确保在 myDirectiveJSfile.js 中同时指定 jquery 和 jquery-ujs

//= require jquery
//= require jquery_ujs

p
peter.hrasko.sk

不要忘记在您的 application.js (Rails 3) 中包含以下行

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

jquery_ujs 包含到我的 rails 应用程序中,它现在可以工作了。


T
Tyler Collier

如果您使用的是 HTTPS with devise,如果您的退出链接指向非安全版本,它就会中断。在后端,它重定向到安全版本。该重定向是一个 GET,这会导致问题。

确保您的链接使用 HTTPS。您可以在 url 助手中使用 protocol: "https" 强制它(确保使用 url 助手而不是路径助手)。

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

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

S
Stephan

问题始于 rails 3.1... 在 /app/assets/javascript/ 中,只需查找 application.js。

如果该文件不存在,请创建一个具有该名称的文件,我不知道为什么我的文件会消失或从未在 "rails new app"... 上创建。

该文件是 jquery... 的实例。


j
jon snow

有很多解决方案。但大多使用这个,

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

或使用适当的 sign_out 方法配置 devise.rb

在设计.rb

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

Z
Zakaria

为您的路径使用 :get:delete 方法:

devise_scope :user do
  match '/users/sign_out' => 'devise/sessions#destroy', :as => :destroy_user_session, via: [:get, :delete]
end

注意:必须有 devise_for :users 与此分开声明。请参阅 dipole_moment 的答案。
U
Uladz Kha

在您的 routes.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 %>

现在的语法是: devise_for :users 然后获取必须放在 devise_scope :user do 注意:singular :user for devise_scope
P
Peter O.

这就是我所做的(使用 Rails 3.0 和 Devise 1.4.2):

确保您的页面加载 rails.js 使用此参数:'data-method' => 'delete' 添加此参数的好主意::rel => 'nofollow'


C
Charles Magid

查看您的 routes.rb 在“devise_for :users”之前是否有“resource :users”,然后尝试交换它们:

作品 devise_for :users 资源 :users 资源失败 :users devise_for :users


C
Code Lღver

页面中的 ':method => :delete' 是 'data-method="delete"' 所以你的页面必须有 jquery_ujs.js,它将使用方法 delete 而不是方法 get 提交链接


m
mikeym

我知道这是一个基于 Rails 3 的老问题,但我只是在 Rails 4.0.4 上遇到并解决了它。所以我想我会为遇到此版本问题的任何人介绍我如何修复它。您的里程可能会有所不同,但这对我有用。

首先确保您已安装 gems 并运行 bundle install。

gem 'jquery-rails'

gem 'turbolinks'

gem 'jquery-turbolinks'

在 application.js 中检查是否需要如下所示的所有内容。

注意这个问题:它是 //= 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>

希望这有助于将某人从这个非常令人沮丧的洞中挖出来!


M
Muntasim

通常,当您收到“无路由匹配”但您认为已定义该路由时,请仔细检查该路由的 http 动词/请求方法(无论是获取、放置、发布、删除等)。

如果您运行 rake 路由,那么您将看到预期的方法,您可以将其与请求日志进行比较。


a
antonkronaj

我正在使用 rails 7。所以这就是我必须这样做的方式。重要的是data: { turbo_method: :delete }

<%= link_to t('nav.logout'), destroy_user_session_path, class: "nav-link", data: { turbo_method: :delete } %>

下面是我生成项目时由 rails 创建的默认值。

应用程序.html.erb

<%= javascript_include_tag "application", "data-turbo-track": "reload", defer: true %>

应用程序.js

import "@hotwired/turbo-rails"
import "./controllers"
import * as bootstrap from "bootstrap"

关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅