Home > Software design >  How can I rearrange my params to get the desired structure?
How can I rearrange my params to get the desired structure?

Time:11-11

I am on a rails 5.07 app. I have some params coming in from a form and that forms partial. I need to restructure these params or re-wire my model associations or try to implement Nested Forms...WHATEVER incantation I need to do in order to restructure / reorder the params from...

Note: I'm not sure how I can be more specific or ask to do only one thing here. As I am asking to do "only one thing"....sooo before you close my question....please be specific as to why? and give an example of how I can ask...this one thing... to rearrange params, differently?

current params


> {"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"}

to Desired params structure

{"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"}

so I can say something like...

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

and result being "7"

Please let me know if I need to include my model associations or anything else. Happy to oblige.

UPDATE:

per request, adding the form and the partial below...

here is the main form that produces the undesired outcome

<!--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  aria-hidden="true"></i> Split</a>-->
          <!--            <a href="/assignments/copy/<%#= skedj.current.id %>" title="copy"><i  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  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 %>

and the partial file _volunteer_shift_fields


<!--<div >-->
  <%= 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>

UPDATE 2:

Big thanks to sam. adjusting my partial has gotten me 90% there. I "think" I just need to move the remaining form elements from parent to child and vice versa to get the rest of the way there. I'll post the outcome once I've tried that as well.

CodePudding user response:

in your _volunteer_shift_fields file, try to bind your form element with the form object. Replace select_tag with vs.select, text_field with vs.text_field. Then Rails will automatically build the desired params.

  • Related