ruby on rails-设计:为什么我的注销链接不起作用?

问题:简而言之,当我尝试安装到我的应用程序的注销链接时,它将无法正常工作。 我想到的就是这里的背景信息(如果您还有其他需要,请戳一下我)...

我有一个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"}

我的routes.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"}

有人有主意吗?

jaydel asked 2020-07-22T19:08:19Z
17个解决方案
83 votes

修复此问题的正确方法(基于REST)将是更改注销链接以使用DELETE方法。 这是一个非常简单的修复程序,更改此操作:

link_to "Log out", destroy_user_session_path

对此:

link_to "Log out", destroy_user_session_path, :method => :delete 
Jay Beale answered 2020-07-22T19:09:15Z
33 votes

当我从jquery删除这一行时,我在rails 3.2上遇到了相同的问题:

//= require jquery_ujs

所以,我认为如果没有,您必须在jquery中插入此行。

PS。 此行为意味着jquery的rails适配器不起作用。 因此,您应该确保它是否已加载到浏览器的html中。 您应该在开发模式下对其进行测试,因为您将在生产环境中使用压缩的js,并且很难在其中找到某些东西。

ka8725 answered 2020-07-22T19:09:44Z
16 votes

问题在于,在您的日志中,注销请求是GET请求。

Started GET "/users/sign_out"

但是登出路线是DELETE

destroy_user_session DELETE /users/sign_out(.:format) 

之所以会得到例外,是因为它与:get创建的一条路线相混淆,就像

edit_user GET /users/(:id)(.:format) {:action=>"edit", :controller=>"users"}

基本上,'sign_out'被误认为是一个id。

我不确定为什么删除链接不会作为DELETE请求通过。 虽然改变

config.sign_out_via = :delete

:get可能会解决此问题。

Olives answered 2020-07-22T19:08:50Z
6 votes

你们两个都需要
link_to "Log out", destroy_user_session_path, method: :delete

&&这些包含在application.js中

//= require jquery
//= require jquery_ujs

。 显然,如果由于某种原因不存在,请不要忘记将其添加到Gemfile中。

gem 'jquery-rails'

webgen answered 2020-07-22T19:10:17Z
4 votes

这是一个古老的问题,但是公认的答案不是解决此问题的正确方法(尽管它可以很好地诊断问题)。

今天当我遇到这个问题时,我的路线文件显示为:

  root :to => 'welcome#index' 

  resources :users    
  devise_for :users

正如Olives提到的那样,resources语句只是导致/ users /任何东西崩溃。 我只需要颠倒路线的顺序即可。

 root :to => 'welcome#index' 

  devise_for :users
  resources :users
pws5068 answered 2020-07-22T19:10:46Z
4 votes

为了执行带有DELETE的请求,需要jQuery。 确保没有从application.js中删除它。

Christoph answered 2020-07-22T19:11:05Z
2 votes

这是一个老问题,但是我想要一种不需要JavaScript的方法。 Rails使用隐藏输入启用“ DELETE”之类的请求,该输入将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>
Ross Allen answered 2020-07-22T19:11:30Z
2 votes

我已经检查了所有这些解决方案,但是没有人为我工作。 最后,我发现在标题中我删除了两行,包括应用程序标签和csrf meta

因此,如果此时有人遇到无法解决的问题-请检查页面标题是否具有(HAML表示法)

= javascript_include_tag 'application'
= csrf_meta_tags 
RafeekPro answered 2020-07-22T19:11:55Z
1 votes

我必须以不同于我的application.rb的方式来处理此问题:

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

仍然失败。 原来我需要在/ environment / development,test和production.rb中设置config.serve_static_assets = true。 这个链接帮助我弄清楚了。

ScottJShea answered 2020-07-22T19:12:19Z
1 votes

您还必须检查一下,是否为2978080908844205005057下的resources :users,并且是链接方法删除

link_to "Logout", destroy_user_session_path, method: :delete

如果两者都正确,那么您的注销按钮应该可以工作

user212131 answered 2020-07-22T19:12:44Z
1 votes

如果您的Rails应用程序中还有多个jquery源,则需要使用Gemfile中指定的默认jquery源。

确保在您的Gemfile中有这个

gem 'jquery-rails'

并且在您的资产中,您没有任何其他JQuery源文件。

在我的情况下,我有第二个JQuery文件,而不是Gemfile中声明的默认文件,因此它引起了冲突。

如果您以前有这些来源,请确保再次进行预编译(如果以前有)

Leonard Kakande answered 2020-07-22T19:13:21Z
1 votes

由于OP提到了devise,并且这个问题也发生在我身上,所以我只想插话。@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 %>
JorgePinon answered 2020-07-22T19:13:50Z
0 votes

我同意使用http DELETE方法更为轻松,我喜欢创建一个简单的端点来使用GET方法销毁用户会话。

通过添加到config / routes.rb

devise_scope :user do
  get '/logout',  :to => 'sessions#destroy'
end
errata answered 2020-07-22T19:14:15Z
0 votes

如果在生产中发现此问题,并且正在使用资产管道,则通常需要:

rake assets:clobber以清除您的公共资产。 然后在提交并推送您的代码之前rake assets:precompile(除非您的推送还进行了预编译,也就是Heroku)。

EARnagram answered 2020-07-22T19:14:39Z
0 votes

原因可能是连接顺序错误bootstrap-sprockets

正确的顺序:

// app/assets/javascripts/application.js

...

//= require jquery
//= require jquery_ujs
//= require turbolinks
//= require bootstrap-sprockets
//= require_tree .
askrynnikov answered 2020-07-22T19:15:04Z
0 votes

正如上面的Tombart所提到的,对我来说,答案是在我的application.js文件中放回rails-ujs调用。

//= 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标签结尾之前添加了新的“页脚”调用。

wsizoo answered 2020-07-22T19:15:41Z
0 votes

1)我觉得您可能需要在gem下安装,方法为:delete的请求将起作用,否则可能会得到

[HTTPS://GitHub.com/rails/jQuery-rails]

2)在application.js中添加以下两行

//= require jquery
//= require jquery_ujs
Gurudath BN answered 2020-07-22T19:16:10Z
translate from https://stackoverflow.com:/questions/6946435/devise-why-doesnt-my-logout-link-work