devise:为什么我的注销链接不工作?

问题:简而言之,当我尝试安装一个注销链接到我的应用程序,它无法正常工作。 这里有尽可能多的上下文,我可以想到放在这里(如果你想要的东西,请戳我)…

我有一个哈姆的观点:

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

它在视图中产生这个:

 <a href="/users/sign_out" data-method="delete" rel="nofollow">Logout</a> 

我validation了在我的config / initializers / devise.rb我有这个设置uncommented和正确的:

 config.sign_out_via = :delete 

我validation了以下路线:

 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 

最后一点是因为我想在自己的控制器中pipe理(编辑,创build和删除)用户。

我收到的错误消息如下所示:

 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"} 

有人有主意吗?

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

 Started GET "/users/sign_out" 

但注销路线是一个删除

 destroy_user_session DELETE /users/sign_out(.:format) 

你得到这个exception的原因是它与resources :users创build的路线之一相混淆resources :users可能会像

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

基本上“sign_out”被误认为是id。

我不知道为什么删除链接不通过DELETE请求。 虽然改变

 config.sign_out_via = :delete 

成为:get可能解决问题。

正确的方法来解决这个,REST明智的,将是改变你的注销链接使用DELETE方法。 这是一个非常简单的修复,改变这一点:

 link_to "Log out", destroy_user_session_path 

对此:

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

当我从application.js这行删除时,我遇到了与rails 3.2相同的问题:

 //= require jquery_ujs 

所以,我认为你必须在你的application.js插入这行,如果你没有在那里。

PS。 这种行为意味着jquery rails适配器不起作用。 所以你应该确定它是否被加载到浏览器的HTML中。 你应该在开发模式下testing它,因为你将在生产中压缩js,并且在那里find一些东西是非常困难的。

这是一个古老的问题,但接受的答案不是解决这个问题的正确方法(尽pipe这是一个很好的诊断问题)。

当我今天跑到这里时,我的路线文件显示为:

  root :to => 'welcome#index' resources :users devise_for :users 

正如橄榄提到的那样,资源声明只是简单地导致/用户/任何东西绊倒。 我只是需要扭转我的路线的顺序…

  root :to => 'welcome#index' devise_for :users resources :users 

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

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

&&这些包含在application.js中

 //= require jquery //= require jquery_ujs 

。 显然,如果由于某些原因,不要忘记将它添加到Gemfile中。

gem 'jquery-rails'

这是一个老问题,但我想要一个不需要JavaScript的方法。 Rails启用“DELETE”,就像使用隐藏input的请求来设置要delete method 。 使用一个真正的<form> ,让Rails生成必要的隐藏input:

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

我不得不以与我的申请不同的方式来解决这个问题。

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

并仍然失败。 原来我需要在/ environment / development,test和production.rb中设置config.serve_static_assets = true 。 这个链接是帮我弄明白的。

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

 link_to "Logout", destroy_user_session_path, method: :delete 

如果两者都是正确的,你的注销button应该工作

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

所以,如果有人有这个问题没有sollution在这一点上 – 检查是否有在页面的标题(HAML符号)

 = javascript_include_tag 'application' = csrf_meta_tags 

由于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助手创build一个类似的forms:

 <%= button_to "Log out", destroy_user_session_path, method: :delete %> 

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

通过将此添加到config / routes.rb

 devise_scope :user do get '/logout', :to => 'sessions#destroy' end 

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

确保你的Gemfile中有这个

 gem 'jquery-rails' 

而在你的资产中你没有任何其他的JQuery源文件。

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

如果您之前有过这些源代码,请务必再次预编译资源

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

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

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

正确的顺序是:

 // app/assets/javascripts/application.js ... //= require jquery //= require jquery_ujs //= require turbolinks //= require bootstrap-sprockets //= require_tree . 

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

 //= require rails-ujs //= require turbolinks 

我最初已经删除它们来阻止脚本中的脚本被重新评估的错误。 我的解决方法是创build一个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' %> 

我将应用程序行保留在我的头文件中,并在我的身体标记结束之前添加了新的“页脚”调用。