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' %>
我将应用程序行保留在我的头文件中,并在我的身体标记结束之前添加了新的“页脚”调用。