【问题标题】:Rails form using GET method regardless of what is specifiedRails 表单使用 GET 方法,无论指定什么
【发布时间】:2016-09-27 05:06:33
【问题描述】:

我有一个用于重置密码的 HTML 表单。它的方法是PATCH,它应该是PasswordResetControllerupdate 方法。但是,在提交时,总是发出GET 请求,而不管指定的method。我可以输入method=ANYTHINGHERE,它总是发出GET 请求。

我的表格很简单:

  <form class="group" action="<%= password_reset_url %>" method="PATCH">
    <input type="hidden" name="authenticity_token" value="<%= form_authenticity_token %>">

    <input type="password" class="password-login" name="new_password" placeholder="New Password">
    <input type="password" class="password-login" name="new_password_verify" placeholder="New Password Confirmation">
    <button class="login-button">Reset Password</button>

  </form>

我的路线似乎井井有条:

password_reset_index   POST   /password_reset(.:format)          password_reset#create
new_password_reset     GET    /password_reset/new(.:format)      password_reset#new
edit_password_reset    GET    /password_reset/:id/edit(.:format) password_reset#edit
password_reset         PATCH  /password_reset/:id(.:format)      password_reset#update
                       PUT    /password_reset/:id(.:format)      password_reset#update

定义为resources :password_reset, only: [:new, :create, :edit, :update]

还有我的控制器:

class PasswordResetController < ApplicationController

    new, edit, create....etc.

    def update
      user = ...
    end

end

创建、新建和编辑都可以正常工作,但在提交表单时甚至没有进入更新方法。我刚收到No route matches [GET] "/password_reset/longTokenString。有任何想法吗?我觉得我在这里已经用尽了我的选择。

这不是this question 的重复,因为令牌字符串正在正确生成。令牌字符串也用作 /password_reset/:id/edit 路由中的 id,并且在那里也可以正常工作。

提前致谢。

【问题讨论】:

    标签: ruby-on-rails forms ruby-on-rails-4


    【解决方案1】:

    根据这里的rails策略,PUTPATCH方法之间的区别是什么。

    如果您来自以前的 Rails 版本,您可能想知道为什么 RESTful 路由的更新操作映射到 HTTP 动词 PATCH 而不是 PUT。在 HTTP 标准文档 RFC 57892 中,它概述了对给定资源的 PUT 请求旨在在源服务器上完全替换它。但是,在 Rails 中更新资源时,很少(如果有的话)在执行更新时替换整个资源。例如,更新 Active Record 模型时,Rails 设置属性 updated_at 时间戳,而不是请求客户端。

    为了遵循更好的 HTTP 语义,Rails 将使用 HTTP 动词 PATCH 进行更新。 PATCH 允许对资源进行全部和部分更新,并且更适合 Rails 更新资源的方式。如果您正在升级现有的 Rails 应用程序,HTTP 动词 PUT 仍将映射到更新操作 RESTful 路由,但建议继续使用 PATCH。

    我将解释“用户编辑”选项在 Rails 中的工作原理。

    app/controllers/users_controller.rb

     def edit
        @user = User.find(params[:id])
     end
    

    对应的用户编辑视图

    app/views/users/edit.html.erb

    <% provide(:title, "Edit user") %>
    <h1>Update your profile</h1>
    
    <div class="row">
    <div class="col-md-6 col-md-offset-3">
    <%= form_for(@user) do |f| %>
    <%= render 'shared/error_messages' %>
    
    <%= f.label :name %>
    <%= f.text_field :name, class: 'form-control' %>
    
    <%= f.label :email %>
    <%= f.email_field :email, class: 'form-control' %>
    
    <%= f.label :password %>
    <%= f.password_field :password, class: 'form-control' %>
    
    <%= f.label :password_confirmation, "Confirmation" %>
    <%= f.password_field :password_confirmation, class: 'form-control' %>
    
    <%= f.submit "Save changes", class: "btn btn-primary" %>
    <% end %>
    

    查看 HTML 源代码

    <form accept-charset="UTF-8" action="/users/1" class="edit_user"
          id="edit_user_1" method="post">
      <input name="_method" type="hidden" value="patch" />
      .
      .
      .
    </form>
    

    注意:注意这里隐藏的输入字段:

    <input name="_method" type="hidden" value="patch" />
    

    形成文档:

    method: (:get|:post|:patch|:put|:delete)
    

    “在选项哈希中。如果动词不是 GET 或 POST,HTML 表单本身支持这些,表单将被设置为 POST,并且名为 _method 的隐藏输入将携带预期的动词供服务器解释。 "

    参考:http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html

    希望我的解释能清楚地理解这个概念。快乐编码:)

    【讨论】:

    • 感谢您非常彻底的回答。有时很难透过树木看到森林。我实际上已经知道这一点,但最近刚刚做了很多 AJAX 补丁调用,以至于它甚至没有进入我的脑海。有时你会进入例行程序,而基本概念就会消失。是时候刷新了……谢谢纳雷什!
    【解决方案2】:

    根据 HTML 标准,您不能添加 put 作为表单的方法。方法属性的唯一有效值是 get 和 post。 &lt;form method="put"&gt; 是无效的 HTML,将被视为 &lt;form&gt;,即发送 GET 请求。

    您也可以使用rails form标签编写表单代码。

    【讨论】:

      【解决方案3】:

      需要记住的几点---

      1. 如果您使用form_for 标签,您不必担心其他任何事情,因为rails 本身使用它的Record identification 来处理创建(POST)、新建(GET) 和更新(UPDATE/PATCH) 操作。
      2. 如果你没有统一使用form_for标签,这是你的情况,你必须完全匹配url,所以你也需要传递id

      例子:-

       <form class="group" action="<%= password_reset_url(@your_model.id) %>" method="PATCH">
      

      希望能帮到你:)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-08-28
        • 1970-01-01
        • 2019-03-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-08
        相关资源
        最近更新 更多