【问题标题】:Rails 3.2 with Devise: logout link stopped working带有设计的 Rails 3.2:注销链接停止工作
【发布时间】:2013-12-20 07:34:23
【问题描述】:

我的应用程序中的注销链接一直工作正常,然后就停止工作了。我已经有一段时间没有测试它了,但是我已经一个月没有对任何与它相关的东西进行任何更改了!当控制器应将其解释为DELETE 请求时,它正在发送GET 请求。这是我的代码:

在我看来,我的 ERB 文件包括这一行:

<li><%= link_to('Log Out', destroy_user_session_path, :method => :delete)%></li>

还包括:

<%= javascript_include_tag "application" %>

这是来自我的application.js

//
//= require jquery
//= require jquery_ujs
//= require underscore
//= require backbone
//= require jquery.serializeJSON
//= require jquery-ui-1.10.3.custom
//= require jquery-ui-touchpunch.min.js
//= require auto_form_bot
//= require_tree ../templates
//= require_tree ./models
//= require_tree ./collections
//= require_tree ./views
//= require_tree ./routers
//= require_tree .

这是我的 gemfile 中的相关内容:

source 'https://rubygems.org'
ruby "1.9.3"

gem 'rails', '3.2.13'
gem 'backbone-on-rails', '~> 1.1'
gem 'compass-rails'
gem 'devise', '>= 3.1.0'
gem 'ejs'
gem 'figaro'
gem 'jquery-rails'
gem 'pg'
gem 'sass-rails',   '~> 3.2.3'

这是实际渲染的 html:

<li><a href="/users/sign_out" data-method="delete" rel="nofollow">Log Out</a></li>

当我点击链接时,这是我得到的错误:

Routing Error
No route matches [GET] "/users/sign_out"

这是我的服务器日志:

Started GET "/users/sign_out" for 127.0.0.1 at 2013-12-19 23:49:24 -0500

ActionController::RoutingError (No route matches [GET] "/users/sign_out")

以下是相关路线:

    new_user_session GET    /users/sign_in(.:format)     devise/sessions#new
        user_session POST   /users/sign_in(.:format)     devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format)    devise/sessions#destroy

链接生成的GET 请求应该会自动更改为DELETE 请求,但它不再是了,我不知道我更改了什么使其停止工作。

即使是陌生人,偶尔也会有效果!相同的链接适用于我应用程序的另一个页面。这是我的应用程序的演示帐户的链接,您将自动登录,因此您可以退出:http://www.form-itable.com/accounts/demo

我无法弄清楚我在这里缺少什么。我知道我可以解决问题,但该链接应该可以正常工作,直到现在都可以正常工作,我想知道为什么不能。

【问题讨论】:

  • 应该有POST请求而不是DELETEGET,因为有些浏览器没有t support DELETE`方法
  • @hawk,你是对的,但是因为它是一个链接,它只做GET,但它应该自动更改为DELETE,因为data-method="delete"部分。它适用于我的应用程序的其他地方。
  • Rails 会将 method: :delete 扩展为类似 &lt;input type="hidden" name="_method" value="delete" /&gt; 的内容,然后只有在此之后,您的服务器才会以 DELETE 请求而不是浏览器来威胁您的请求。
  • 我认为您的 javascript 部分检查有问题 jquery_ujs 在每个页面上都按预期加载,并且每个页面上都会触发 document.ready 事件
  • 是的,好像 rails.js 在页面加载后没有被调用。 handleMethod 是将获取方法更改为删除的方法。或者,您可以在 devise.rb 中将 config.sign_out_via = :delete 更改为 config.sign_out_via = :get 以使事情正常进行。

标签: jquery html ruby-on-rails ruby-on-rails-3 devise


【解决方案1】:

当我阅读jquery_ujs files 时,我看到它似乎通过在document 上设置事件侦听器将链接从GET 转换为DELETE,如下所示:

// Link elements bound by jquery-ujs
linkClickSelector: 'a[data-confirm], a[data-method], a[data-remote], a[data-disable-with]'

...

$document.delegate(rails.linkClickSelector, 'click.rails', function(e) {
  var link = $(this), method = link.data('method'), data = link.data('params'), metaClick = e.metaKey || e.ctrlKey;
... more code ...

有一次在我的应用程序中,我遇到了一个复杂的情况,我需要从document 中删除click 事件,并且由于我没有使用任何其他点击处理程序,所以我只调用了$(document).off('click');删除在document 上监听点击事件的所有内容。这显然是一件非常糟糕的事情。我用专门删除了我的点击处理程序的东西替换了该行,一切都恢复了。

教训是,如果您使用 jQuery_ujs 永远不要在 document 上使用 off(),除非您可以针对特定的处理程序

【讨论】:

    猜你喜欢
    • 2014-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多