Rails 的 link_to 方法:GET 啥时候应该 DELETE

Posted

技术标签:

【中文标题】Rails 的 link_to 方法:GET 啥时候应该 DELETE【英文标题】:Rails' link_to method: GETing when it should DELETERails 的 link_to 方法:GET 什么时候应该 DELETE 【发布时间】:2011-11-19 22:09:55 【问题描述】:

我正在关注 Michael Hartl 的 Rails 教程,出于某种原因,以下代码:

<%= link_to 'delete', user, :method => :delete, :confirm => "You sure?",
                                :title => "Delete #user.name" %>

发出 GET 请求(我通过检查 rails 服务器日志进行了验证)。我还验证了以下行在我的应用程序视图中:

<%= javascript_include_tag :all %>

有一件事我不太明白,这可能是我的问题的根源:“删除”方法在哪里定义?我在Hartl's source code 中验证了他在控制器中定义了一个“销毁”方法,而不是“删除”。但即使我将 link_to 更改为 :method => :destroy,它也只会发出一个 GET。

我使用的是 Rails 3.1。有什么建议吗?

【问题讨论】:

【参考方案1】:

大多数浏览器实际上并不支持 DELETE 动词,因此 Rails 通过修改它生成的 html 来伪造它。 Rails 添加了一个名为data-method 的HTML5 属性并将其设置为"delete"。因此,当用户点击链接时,它实际上是作为 GET 请求发出的,但 data-method 属性允许一些 Rails 魔术,这意味着您的路由代码应该将其识别为 DELETE 请求。

编辑:

您可以在控制台中自行测试。运行 bundle exec rails c 进入控制台,查看生成的 HTML:

helper.link_to "delete", "foobar/delete", :method => 'delete'

HTML 应如下所示:

<a href="foobar/delete" data-method="delete" rel="nofollow">delete</a>

【讨论】:

谢谢,杰加森!这是 Rails 为我的“删除”生成的 HTML -- delete -- 一切看起来都很好,但是当我点击这个链接时并没有删除。我正在使用 Chrome,并且通常对 Javascript 没有任何问题。知道我可以在哪里寻找问题吗? 您的routes.rb 文件是什么样的? 我的在这里:github.com/koggit/global2local-interpret/blob/master/config/… Hartl 在这里:github.com/railstutorial/sample_app/blob/master/config/… 相比之下看起来还不错,虽然我还不太了解路线。 你能判断你的 UsersController#destroy 方法在点击该链接时是否正在触发吗?插入打印线或其他什么? 谢谢--您的回复帮助我找到了找到这篇文章的关键字,它有一个解决方案 -- ***.com/questions/7281907/… -- 不幸的是,尽管工作,但不清楚 为什么 这个解决方案。那好吧。 :) 再次感谢!【参考方案2】:

我在 Michael 的教程中遇到了同样的问题。 data-method="delete" 实际上按预期工作 - 它确实调用了控制器中的销毁操作。它尝试GET(并最终失败)的原因如下:

您会注意到控制器中的before_filter 之一设置为signed_in_user,而在session_helper.rb 中,您会注意到signed_in_user 调用store_location(私有方法),它将 session[:return_to] 更新为当前 URL。

所以,回到控制器的销毁操作,它会尝试redirect_back_or,结果是GET current_url。我修改了signed_in_user 助手,只在用户尚未登录时调用store_location

【讨论】:

【参考方案3】:

还要检查它是否在您的 application.js 中:

//= require jquery
//= require jquery_ujs 

显然我有没有 jquery_ujs 的 jquery,在我添加它之前我遇到了同样的问题。

【讨论】:

【参考方案4】:

你应该使用下面的代码

<%= button_to "delete", @user_current, :method => "delete" %>

它会解决这个问题或添加这行 //= require jquery_ujs 到 application.js 并使用:

 <%= link_to 'delete', user, :method => :delete, data: :confirm => "You sure?"  ,
                            :title => "Delete #user.name" %>

【讨论】:

如果你不想包含 JQuery,我相信切换 link_to > button_to 会解决这个问题。 我同意。如果要使用 link_to,请将 jquery_ujs 添加到 application.js【参考方案5】:

由于浏览器不支持DELETE 动词,Rails 通过标准GETPOST 模拟DELETE 请求来解决此问题。 method: :delete 的工作方式是使用 JavaScript 处理程序处理带有 data-method="delete" 的所有链接,它会修改请求,因此 Rails 将其作为 DELETE 处理。此 JavaScript 处理程序由 jquery_ujs 库提供。

有几件事可能出错:

    确保jqueryjquery_ujs 都包含在您的application.js 中。没有这两者,什么都不会处理数据属性。 确保相关链接确实指定了method: :delete 选项。 确保由于某种原因您没有停止相关链接的事件传播,例如:
$( 'a' ).click( function( event ) 
    event.stopPropagation()
)

因为这会阻止 jquery_ujs 处理程序被执行,并且请求将永远不会被修改,并且仍然只是一个标准的 GET。

【讨论】:

【参考方案6】:

在轨道 5 上:

有同样的问题,所有的“删除”帖子都被泄露了,影响了我的 crud 页面并设计了注销...为了解决这个问题,我所要做的就是:

//= 需要 rails-ujs

【讨论】:

【参考方案7】:

我们只需要添加下面的代码行

//= require jquery_ujs 

这似乎是一个错误:))

【讨论】:

以上是关于Rails 的 link_to 方法:GET 啥时候应该 DELETE的主要内容,如果未能解决你的问题,请参考以下文章

使用方法对 link_to 的 ajax 请求:在禁用 javascript 的情况下放入 rails

Rails 3.2 `link_to`(在电子邮件中)与`method: :put`仍在产生GET请求

Rails 是不是支持带有方法 post 的 link_to?

14--Rails的ActiveView2

如果 JS 可能被禁用,Rails 4 link_to :delete 的最佳方法是啥?

Rails link_to 方法: :delete