You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails 5.07项目如何调整表单参数以得到期望的嵌套结构

Rails 5.07 表单参数结构调整需求

需求说明

在Rails 5.07环境下开发应用时,现有表单及其局部组件提交的参数结构不符合业务要求,需要通过调整参数结构、修改模型关联或优化嵌套表单实现参数重排。
注:当前核心目标仅为完成参数结构转换,若问题描述需要优化,可告知具体原因及优化示例。


参数结构对比

现有参数结构

{"utf8"=>"✓",
"assignment"=>{"volunteer_shift_attributes"=>{"volunteer_task_type_id"=>"41",
"roster_id"=>"7", "program_id"=>"9", "set_description"=>"Nov10",
"set_date"=>"2021-01-08"}, "start_time(1i)"=>"2021",
"start_time(2i)"=>"11", "start_time(3i)"=>"10",
"start_time(4i)"=>"08", "start_time(5i)"=>"00",
"end_time(1i)"=>"2021", "end_time(2i)"=>"11", "end_time(3i)"=>"10",
"end_time(4i)"=>"09", "end_time(5i)"=>"00", "notes"=>"Nov10",
"contact_id"=>"166574", "closed"=>"0", "lock_version"=>"0"},
"contact_element_prefix"=>"contact", "commit"=>"Submit",
"controller"=>"volunteer_events", "action"=>"create_shift"}

期望参数结构

{"assignment"=>{"volunteer_shift_attributes"=>
{"volunteer_task_type_id"=>"41", "roster_id"=>"7", "program_id"=>"9", 
"set_description"=>"fonso says wtf?"}, "set_date"=>"2021-01-07", 
"contact_id"=>"166574", "closed"=>"0", "start_time(4i)"=>"12", 
"start_time(5i)"=>"00", "end_time(4i)"=>"13", "end_time(5i)"=>"00", 
"notes"=>"fuuuuuuuuuk"}, "lock_versions"=>["0"], 
"contact_element_prefix"=>"contact", "commit"=>"Update", 
"controller"=>"volunteer_events", "action"=>"create_shift"}

调整后可通过如下代码获取目标值,预期返回结果为"7":

params["assignment"]["volunteer_shift_attributes"]["roster_id"] 

若需要模型关联等补充信息可告知,会同步对应内容。


补充表单代码

主表单代码

<!--This is NEW action form-->

<%= form_for @assignment, :url => @my_url, remote: true do |f| %>

<!--  #FIXME need a fields_for 4 the volunteer_event-->

  <div class="">
    <div class="modal-body  d-flex">
      <div class="col-sm-8 border-right">
        <section id="location-date-time-notes" class="flex">
          <% if @assignment.errors.any? %>
            <div id="error_explanation">
              <h2><%= pluralize(@assignment.errors.count, "error") %> prohibited this assignment from being saved:</h2>
              <ul>
                <% @assignment.errors.full_messages.each do |message| %>
                  <li><%= message %></li>
                <% end %>
              </ul>
            </div>
          <% end %>

          <!--VOLUNTEER SHIFT-->
          <!--TODO: make this a partial under field_for-->
          <%= f.fields_for :volunteer_shift do |builder| %>
            <%= render 'assignments/volunteer_shift_fields', vs: builder %>
          <% end %>
          <!--TODO: Volunteer Shift end -->


          <div id="time-row" class="d-flex flex-row">
            <label for="assignment_time" class="col-sm-3 p-2">
              <i class="fa fa-clock-o fa-lg" aria-hidden="true"></i> Time:
            </label>
            <div class="col- p-2">
              <div class="myStartTime"  id="start_time_<%= @assignment.id %>">
                <%= f.time_select :start_time %>
              </div>
            </div>
            <div class="col- p-2"><i class="fa fa-arrows-h fa-lg" aria-hidden="true"></i></div>
            <div class="col-sm-3 p-2">
              <div class="myEndTime"  id="end_time_<%= @assignment.id %>">
                <%= f.time_select :end_time %>
              </div>
            </div>
          </div>
          <div class="d-flex flex-row">
            <label for="assignment_notes" class="col-sm-3 p-2">
              <i class="fa fa-clipboard fa-lg" aria-hidden="true"></i> Notes:
            </label>
            <div class="col-sm-9 p-2">
              <div class="d-flex flex-row">
                <span> Notes only get saved if a contact is assigned the shift, and get removed when the contact is removed from the shift.</span>
                <div class="">
                  <%= f.label :notes %>
                  <%= f.text_area :notes %>
                </div>
              </div>
            </div>
          </div>
        </section>
      </div>

      <div class="col-sm-4">

        <!-- Contact Section-->
        <div id="contact_section">
          <% if @assigned_contacts &&  @assigned_contacts.length > 0 %>
            <h2>Previously Assigned Contacts</h2>
            <% @assigned_contacts.each do |c| %>
              <%= label_tag "assigned_contacts[#{c.id}]", "Are you sure you want to remove the currently scheduled volunteer, #{c.display_name} (##{c.id}), from the assignment(s)?" %>
              <%= check_box_tag "assigned_contacts[#{c.id}]", "replace", @replaced_contacts.include?(c.id) %>
            <% end %>
          <% end %>
          <input id="contact_element_prefix" name="contact_element_prefix" type="hidden" value="contact">
          <div class="name large flex-row">
            <%= f.label :contact_id %><%= f.text_field :contact_id %>
          </div>

          <div id="display-contact" class="d-flex flex-row">
            <% if f.object.contact_id %>
              <%= render partial: 'contacts/contact_display', locals: { contact:f.object.contact} %>
            <% else %>
              <div>no contact attatched- _form.html called</div>
              <%#= link_to 'Show Contact', contact_path(f.object.contact_id),  remote: true %>
            <% end %>
          </div>

          <!--    FIXME: replace this logic stack with AJAX-->
          <%#= contact_field("@obj", "contact_id",
        :locals => {:options => {
        :object_name => f.object_name.to_s,
        :field_name => 'contact_id',
        :on_display => 'display_disciplinary_notes(); display_contact_notes();'
        }}
                      ) %>
          <%= f.label :closed, "Is this slot closed?" %>
          <%= f.check_box :closed %>

          <!--Contact Section END-->

          <!--Attendance / Call Status start-->
          <% if f.object.id && f.object.contact_id %>

            <div class="flex-row">
              <div class="col-25"><label for="assignment_attendance_type_id">Attendance:</label></div>
              <div class="col-75"><%= select(f.object_name,
                                             "attendance_type_id",
                                             AttendanceType.all.sort_by(&:id).collect {|p| [ p.name, p.id ] },
                                             :include_blank => true) %></div>
            </div>
            <div class="flex-row">
              <div class="col-25"><label for="assignment_call_status_type_id">Call status:</label></div>
              <div class="col-75"><%= select(f.object_name,
                                             "call_status_type_id",
                                             (["not called yet", ""] + CallStatusType.all.sort_by(&:id).collect {|p| [ p.name, p.id ] }),
                                             :include_blank => false) %></div>

            </div>
          <% end %>
          <!-- Attendance / Call Status End-->

          <!-- LOCK VERSION-->
          <div class="flex-row">
            <div class="col-25">
              <%= f.label :lock_version %>
            </div>
            <div class="col-75">
              <%= f.number_field :lock_version %>
            </div>
          </div>
          <!-- LOCK end-->
        </div>

      </div>
    </div>

    <div class="modal-footer d-flex justify-content-between">
      <div class="edit_icons d-flex flex-row">
        <div class="d-flex flex-column">
          <!--            <a href="/assignments/edit/<%#= skedj.current.id %>" title="split"><i class="fa fa-share-alt-square fa-lg" aria-hidden="true"></i> Split</a>-->
          <!--            <a href="/assignments/copy/<%#= skedj.current.id %>" title="copy"><i class="fa fa-files-o fa-lg" aria-hidden="true"></i> Copy</a>-->
        </div>
        <div class="d-flex flex-column">
          <%#= link_to '<i class="fa fa-pencil-square-o fa-lg" aria-hidden="true"></i>Edit'.html_safe, edit_assignment_path,  remote: true%>
          <!--            <a href="#" onclick="reassign(<%#= skedj.current.id %>); return false;" title="reassign"> <i class="fa fa-refresh fa-lg" aria-hidden="true"></i> Reassign</a>-->
        </div>
      </div>
      <div>
        <button type="button" class="btn btn-secondary mr-2" data-dismiss="modal">Close</button>
        <button type="button" class="btn btn-primary"><%= f.submit "Submit" %></button>
        <!--              <input id="assignment_submit" name="commit" type="submit" value="Update">-->
      </div>
    </div>

  </div>

<% end %>

局部组件_volunteer_shift_fields代码

<!--<div class="name large flex-row">-->
  <%= vs.label :volunteer_shift %>
<!--</div>-->
<div id="volunteer_shift" class="d-flex flex-row">
  <div class="col-sm-12 p-2">
    <div id="volunteer_shift" class="text-right">
      <div class="field">
        <%= vs.label :volunteer_task_type_id %>
        <%= vs.select 'volunteer_task_type_id', options_from_collection_for_select([VolunteerTaskType.new(:description => ""),  VolunteerTaskType.instantiables.effective_on(Date.today)].flatten, "id", "description")  %>
      </div>
      <div class="field">
        <%= vs.label :roster_id %>
        <%= vs.select 'roster_id', options_from_collection_for_select([Roster.new(:name => ""), Roster.all].flatten, "id", "name") %>
      </div>
      <div class="field">
        <%= vs.label :program_id %>
        <%= vs.select 'program_id', options_from_collection_for_select([Program.new(:name => ""), Program.where(:volunteer => true)].flatten, "id", "name")%>
      </div>
      <div class="field">
        <%= vs.label :set_description, "Description" %>
        <%= vs.text_area(:set_description) %>
      </div>
      <div class="field">
        <%= vs.label :set_date, "Date" %>
        <%= vs.text_field(:set_date) %>
      </div>
    </div>
  </div>
</div>

进度更新

调整局部组件后已经完成了90%的预期效果,剩余仅需要将其余表单元素在父子层级间移动即可完成全部调整,测试完成后会同步最终结果。


内容的提问来源于stack exchange,提问作者thefonso

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 23:42:00