简体   繁体   English

Rails 在添加新的嵌套记录时错误解释 http 方法

[英]Rails wrongly interpreting http method when adding new nested record

I've got a form with nested attributes fields, made with form_with model:我有一个带有嵌套属性字段的表单,使用form_with model:

<%= form_with model: [ :admin, @event ], local: true, class: "event-form" do |form| %>
  <%= form.hidden_field :event_category_id %>

  <div class="row">
    <div class='col-xs-12 col-sm-7'>
      <ul class="nav nav-tabs" role="tablist">
        <li role="presentation" class="active">
          <a href="#<%= dom_id @event %>-pl-tab" aria-controls="pl" role="tab" data-toggle="tab">Wersja Polska</a>
        </li>
        <li role="presentation"><a href="#<%= dom_id @event %>-en-tab" aria-controls="en" role="tab" data-toggle="tab">Wersja Angielska</a></li>
      </ul>
      <div class="tab-content">
        <div role="tabpanel" class="tab-pane panel panel-default fade in active" id="<%= dom_id @event %>-pl-tab">
          <div class='panel-body'>
            <div class='checkbox'>
              <label>
                <%= form.check_box :pl_active, class: 'panel-activator' %>
                Aktywna
              </label>
            </div>
...

and in that form i'm using fields_for nested attributes:在那种形式中,我使用fields_for嵌套属性:

<div class='panel panel-default'>
        <div class='panel-heading'>
          <div class='row'>
            <div class='col-xs-6'>
              <%= form.label :event_variants %>
            </div>
            <div class='col-xs-6 text-right'>
              <%=link_to 'Dodaj', new_admin_event_variant_path( event_id: @event, index: @event.event_variants.size ), id: "add-event-variant", class: 'btn btn-sm btn-primary', remote: true %>
            </div>
          </div>
        </div>
        <div class='panel-body event-variants sortable'>
          <%- @event.event_variants.each_with_index do |event_variant, index| %>
            <%= render partial: 'admin/event_variants/form', locals: { event_variant: event_variant, index: index } %>
          <% end %>
        </div>
      </div>

and a partial looks like:部分看起来像:

<div id="event_variant-<%= index %>" class='panel panel-default'>
  <%= fields_for "event[event_variants_attributes][]", event_variant, child_index: index do |fields| %>
    <%= fields.hidden_field :id %>
    <%= fields.hidden_field :position %>
    <%= fields.hidden_field :_destroy %>
    <div class='panel-heading'>
      <div class='row'>
        <div class='col-xs-6 variant-title'>
          <%= event_variant.pl_title || 'Nowy element' %>
        </div>
        <div class='col-xs-6 text-right'> 
          <label class='btn btn-sm btn-primary'>
            <%= event_variant.image&.file.present?  ? 'Zmień zdjęcie' : 'Dodaj zdjęcie' %>
            <%= fields.file_field :image, style: 'display:none', class: 'add-image' %>
          </label>
          <div class='btn btn-sm btn-danger remove-variant'>Usuń</div>
        </div>
      </div>
    </div>
    <div class='image-container' style="background-image:url('<%= event_variant.image&.file.present? ? event_variant.image.url : image_path('no-image-icon') %>')" >
    </div>
    <div class='panel-body'>
      <ul class="nav nav-tabs" role="tablist">
        <li role="presentation" class="active">
          <a href="#event_variant-<%= index %>-pl-tab" aria-controls="pl" role="tab" data-toggle="tab">Wersja Polska</a>
        </li>
        <li role="presentation"><a href="#event_variant-<%= index %>-en-tab" aria-controls="en" role="tab" data-toggle="tab">Wersja Angielska</a></li>
      </ul>
      <div class="tab-content">
        <div role="tabpanel" class="tab-pane panel panel-default fade in active" id="event_variant-<%= index %>-pl-tab">
          <div class='panel-body'>
            <div class='checkbox'>
              <label>
                <%= fields.check_box :pl_active, class: 'panel-activator' %>
                Aktywna
              </label>
            </div>
            <div class="form-group">
              <%= fields.label :pl_title %>
              <%= fields.text_field :pl_title, class: 'form-control', disabled: !event_variant.pl_active %>
            </div>
            <div class="form-group">
              <%= fields.label :pl_description %>
              <%= fields.text_field :pl_description, class: 'form-control', disabled: !event_variant.pl_active %>
            </div>
          </div>
        </div>
        <div role="tabpanel" class="tab-pane panel panel-default fade" id="event_variant-<%= index %>-en-tab">
          <div class='panel-body'>
            <div class='checkbox'>
              <label>
                <%= fields.check_box :en_active, class: 'panel-activator' %>
                Aktywna
              </label>
            </div>
            <div class="form-group">
              <%= fields.label :en_title %>
              <%= fields.text_field :en_title, class: 'form-control', disabled: !event_variant.en_active %>
            </div>
            <div class="form-group">
              <%= fields.label :en_subtitle %>
              <%= fields.text_field :en_description, class: 'form-control', disabled: !event_variant.en_active %>
            </div>
          </div>
        </div>
      </div>
    </div>
  <% end %>
</div>

thats attributes are has_many related with main model, so beside fields to edit each of nested model, I can click to render new fields_for partial to create nem nested record - common thing I guess:那是与主要 model 相关的has_many属性,因此除了编辑每个嵌套 model 的字段之外,我可以单击以呈现新fields_for partial 以创建 nem 嵌套记录 - 我猜是常见的事情:

<%=link_to 'Dodaj', new_admin_event_variant_path( event_id: @event, index: @event.event_variants.size ), id: "add-event-variant", class: 'btn btn-sm btn-primary', remote: true %>

going to:即将:

def new
    @event = Event.find params[:event_id]
    @event_variant = @event.event_variants.build( pl_active: false, en_active: false )
    @index = params[:index]
  end

and rendering js.erb :并渲染js.erb

$('.event-variants').append("<%= j render( partial: 'form', locals: { event_variant: @event_variant, index: @index } ) %>")

the problem starts when i'm trying to edit main record.当我尝试编辑主记录时,问题就开始了。 When I'm only changing values of fields, adding images, etc. no matter if in main or nested fields its working ok, sending PATCH, updating record and nested ones.当我只更改字段值、添加图像等时,无论是在主字段还是嵌套字段中,它都可以正常工作,发送 PATCH,更新记录和嵌套字段。

BUT: when I'm trying to add new nested record, by those fields rendered via js.erb , form is send with POST instead of PATCH to route: /events/:id and of course its generating RoutingError :但是:当我尝试添加新的嵌套记录时,通过js.erb呈现的那些字段,表单使用 POST 而不是 PATCH 发送到 route: /events/:id ,当然还有它生成RoutingError

Invalid or incomplete POST params
Started POST "/admin/events/14" for 127.0.0.1 at 2019-09-16 11:19:11 +0200

ActionController::RoutingError (No route matches [POST] "/admin/events/14"):

form attributes are not changing.表单属性没有改变。 HTML still looks like: HTML 仍然看起来像:

<div class="panel-body">
  <form class="event-form" enctype="multipart/form-data" action="/admin/events/14" accept-charset="UTF-8" method="post">
    <input name="utf8" type="hidden" value="✓">
    <input type="hidden" name="_method" value="patch">
    <input type="hidden" name="authenticity_token" value="Z3Uhd6EgZ+N16P5MKbqLDs3F1d94iEokD4O5q63V04q/ofFblB5sRCmEO2m+coHayDrQ/zDNVHSzfSzmDGrxog==">
    <input type="hidden" value="2" name="event[event_category_id]">

    <div class="row">
      <div class="col-xs-12 col-sm-7">
        <ul class="nav nav-tabs" role="tablist">
          <li role="presentation" class="active">
            <a href="#event_14-pl-tab" aria-controls="pl" role="tab" data-toggle="tab">Wersja Polska</a>
          </li>
          <li role="presentation"><a href="#event_14-en-tab" aria-controls="en" role="tab" data-toggle="tab">Wersja Angielska</a></li>
        </ul>
        <div class="tab-content">
          <div role="tabpanel" class="tab-pane panel panel-default fade in active" id="event_14-pl-tab">
            <div class="panel-body">
              <div class="checkbox">
                <label>
                  <input name="event[pl_active]" type="hidden" value="0">
                  <input class="panel-activator" type="checkbox" value="1" checked="checked" name="event[pl_active]">
                Aktywna
                </label>
...

even with _method field set to PATCH even if I manualy set a method in form_with by method: @event.persisted??:patch::post即使_method字段设置为 PATCH,即使我通过方法在 form_with 中手动设置method: @event.persisted??:patch::post

Everything works correctly when no new nested record.当没有新的嵌套记录时一切正常。 And last but not least, I'm not changing anything via js onSubmit nor onClick when submitting.最后但并非最不重要的一点是,提交时我不会通过 js onSubmitonClick更改任何内容。

Any ideas what could went wrong here?有什么想法可以在这里出错吗?

I got this problem when a form field wasn't valid.当表单字段无效时,我遇到了这个问题。

name="blah[]" # this isn't valid

See ActionController::BadRequest (Invalid request parameters: expected Array (got Rack::QueryParser::Params) on ajax post请参阅ajax 帖子上的 ActionController::BadRequest(无效的请求参数:预期的 Array (got Rack::QueryParser::Params)

Putting a pry in this file helped me out /2.7.4/lib/ruby/gems/2.7.0/gems/rack-2.2.3.1/lib/rack/method_override.rb在这个文件中插入一个pry帮助我解决了/2.7.4/lib/ruby/gems/2.7.0/gems/rack-2.2.3.1/lib/rack/method_override.rb

def method_override_param(req)
   binding.pry
   req.POST[METHOD_OVERRIDE_PARAM_KEY]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM