【问题标题】: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。有什么建议吗?

【问题讨论】:

    标签: ruby-on-rails-3 httpverbs


    【解决方案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 方法在点击该链接时是否正在触发吗?插入打印线或其他什么?
    • 谢谢--您的回复帮助我找到了找到这篇文章的关键字,它有一个解决方案 -- stackoverflow.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 库提供。

        有几件事可能出错:

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

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

        【讨论】:

          【解决方案6】:

          在轨道 5 上:

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

          //= 需要 rails-ujs

          【讨论】:

            【解决方案7】:

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

            //= require jquery_ujs 
            

            这似乎是一个错误:))

            【讨论】:

              猜你喜欢
              • 2013-07-18
              • 2015-08-16
              • 2012-03-23
              • 2017-08-09
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多