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 通过标准GET
或POST
模拟DELETE
请求来解决此问题。 method: :delete
的工作方式是使用 JavaScript 处理程序处理带有 data-method="delete"
的所有链接,它会修改请求,因此 Rails
将其作为 DELETE 处理。此 JavaScript 处理程序由 jquery_ujs
库提供。
有几件事可能出错:
-
确保
jquery
和jquery_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?