【问题标题】:Rails remote form collection_select onchange errorRails远程表单collection_select onchange错误
【发布时间】:2018-02-26 03:11:17
【问题描述】:

我正在尝试在更改选择选项时自动提交远程表单。当我从表单标签中删除 remote: true 时,一切正常,除了我不希望每次都重新加载页面。

我使用的是 Rails 5.1.4。

代码

<%= form_for @foo, remote: true do |f| %>

    ... fields

    <%= f.collection_select :bar_id, @list, :id, :name,
       {include_blank: '-'}, { onchange: 'this.form.submit();'} %>

<% end %>

控制器

def update
  respond_to do |format|
    if @foo.update(foo_params)
      format.html { redirect_to @foo }
      format.json { render :show, status: :ok, location: @foo }
    else
      format.html { render :edit }
      format.json { render json: @foo.errors, status: :unprocessable_entity }
    end
  end
end

在视图中更新选择时出现以下错误:

ActionController::InvalidAuthenticityToken

我假设this.form.submit(); 是问题所在。我怎样才能让这个表单成功提交?

【问题讨论】:

    标签: ruby-on-rails ajax ruby-on-rails-5


    【解决方案1】:

    尝试以下简单的方法将authenticity_token: true 添加到您的表单标签中,如下所示

    <%= form_for @foo, remote: true, authenticity_token: true do |f| %>
    

    它应该可以工作,至少对我有用。

    评论后更新

    如果你使用remote: true,你需要使用partial,如果你的表单在new.html.erb,然后剪下表单部分并为表单创建一个partial,比如_form.html.erb,然后将它渲染成new.html.erb,就像

    new.html.erb

    <div id="my-form">
       <%= render partial: "form" %>
    </div>
    

    然后根据您的主文件创建一个js.erb 文件,如new.js.erb 并将这一行放在

    $("#my-form").html("<%= escape_javascript(render("form")) %>");
    

    在您的控制器上添加format.js,如下所示

    format.html { redirect_to @foo } 
    format.js 
    format.json { render :show, status: :ok, location: @foo }
    

    有关 RoR-5 的完整 jQuery/AJAX 参考,您可以阅读 this tutorial,这将有助于提高您的 jQuery/AJAX 技能

    希望能成功

    【讨论】:

    • 似乎可以修复错误显示,但页面仍在更改选择时重新加载。我更新了原始帖子以包含控制器操作代码。
    • @Matt 查看更新的答案,您需要创建一个部分表单以使用 ajax 表单提交而不重新加载整个页面,我已经逐步描述了请按照此操作然后我希望您能实现您的目标
    • 我已经进行了这些更改。一切正常,但页面仍在重新加载。在控制台中,我收到了 Redirected to ... 消息。控制器中的format.html { redirect_to @foo } 行是否导致此问题?
    • @Matt 将format.js { redirect_to @foo } 用于您的控制器操作
    • 我将控制器中的format.html { redirect_to @foo } 替换为format.js { redirect_to @foo },现在出现ActionController::UnknownFormat 错误。
    【解决方案2】:

    将此行添加到您的表单中。

    <%= tag(:input, :type => "hidden", :name => request_forgery_protection_token.to_s, :value => form_authenticity_token) %>
    

    你的表格应该是这样的:

       <%= form_for @foo, remote: true do |f| %>
            <%= tag(:input, :type => "hidden", :name => request_forgery_protection_token.to_s, :value => form_authenticity_token) %>
            ... fields
    
            <%= f.collection_select :bar_id, @list, :id, :name,
               {include_blank: '-'}, { onchange: 'this.form.submit();'} %>
    
        <% end %>
    

    【讨论】:

      【解决方案3】:

      真实性令牌是在您的视图中生成的随机值,用于证明请求是从您网站上的表单提交的,而不是从其他地方提交的。这可以防止 CSRF 攻击

      您可以通过两种方式避免上述错误

      1) 在应用控制器中添加如下代码

      skip_before_filter :verify_authenticity_token  
      

      参考链接:http://api.rubyonrails.org/classes/ActionController/RequestForgeryProtection/ClassMethods.html

      2) 在表单中添加authenticity_token

      <%= hidden_field_tag :authenticity_token, form_authenticity_token %>
      

      &lt;%= csrf_meta_tags %&gt;

      【讨论】:

        猜你喜欢
        • 2015-11-27
        • 2016-04-17
        • 2014-01-02
        • 2014-05-28
        • 2020-05-01
        • 2015-03-19
        • 1970-01-01
        • 1970-01-01
        • 2018-12-06
        相关资源
        最近更新 更多