0

I am having an issue looping through nested form parameters using Stimulus Rails Nested Form. What I have is a nested form where people can select one or many schedules they want to apply the event to, and also create one or many sets of schedule time ranges. So I could say Building A and B on Mon-Wed are going to have an event from 7Am to 12PM. Thurs/Fri an event from 8:00AM to 5:00PM. Any help is appreciated!

I need to keep this info on one table for various reasons so I am trying to loop through the schedules, then loop through the days and times in the time ranges and create separate events for them.

In my create method I have this:

def create
    scheduleevent_params[:schedule_ids].each do |schedule_id|
      scheduleevent_params[:schedtimeranges_attributes].each do |key, value|
        value[:days].each do |day|
          @scheduleevent = Scheduleevent.new(schedule_id: schedule_id, day: day, title: scheduleevent_params[:title],
          description: scheduleevent_params[:description], start_date: scheduleevent_params[:start_date], end_date: scheduleevent_params[:end_date], 
          start_time:  value[:start_time], end_time:  value[:end_time] )
          @scheduleevent.user_id = current_user.id
        end
      end
    end

    respond_to do |format|
      if @scheduleevent.save
        params[:start_date] = @scheduleevent.start_date.to_date
        format.turbo_stream
        format.html { redirect_to scheduleevent_url(@scheduleevent), notice: "Scheduleevent was successfully created." }
        format.json { render :show, status: :created, location: @scheduleevent }
      else
        format.html { render :new, status: :unprocessable_entity }
        format.json { render json: @scheduleevent.errors, status: :unprocessable_entity }
      end
    end
  end

I am getting the error undefined method `each' for nil:NilClass on the [:days].each secondary loop.

params:

def scheduleevent_params
  params.require(:scheduleevent).permit( :title, :day, :start_time, :end_time, :description, :start_date, :end_date, :repeattypeid, :hexcolor, :scheduleinstid, :locked, schedule_ids: [],
   schedtimeranges_attributes: [ :id, :start_time, :end_time, :repeattype, :_destroy, days: [] ])
end

Here is what is coming through:

  {"title"=>"DW1",
   "description"=>"DW1",
   "start_time"=>"2022-10-24 00:00",
   "end_time"=>"2022-10-28 00:00",
   "schedtimeranges_attributes"=>{"1666122012736"=>{"days"=>["1", "2", "3"], "start_time"=>"12:00 PM", "end_time"=>"6:00 PM", "_destroy"=>"false"}},
   "schedule_ids"=>["", "1", "2"]},

form:

<%= form_with(model: scheduleevent, class: "contents", data: { controller: 'nested-form', nested_form_wrapper_selector_value: '.nested-form-wrapper' }) do |form| %>
<template data-nested-form-target="template">
   <%= form.fields_for :schedtimeranges, Schedtimerange.new, child_index: 'NEW_RECORD' do |schedtimeranges| %>
       <%= render "schedtimerange_form", form: schedtimeranges %>
   <% end %>
</template>
<%= form.fields_for :schedtimeranges do |schedtimeranges| %>
    <%= render "schedtimerange_form", form: schedtimeranges %>
<% end %>
<% end %>
2
  • What is it that you actually expect this code to do? The only thing happening here is that you're reassigning the @scheduleevent instance variable for each iteration of the loop. Its very hard to fix your code when we just have the completly broken code and no discription of what its indended to do. Commented Oct 18, 2022 at 19:59
  • I have updated my OP with more info. Commented Oct 18, 2022 at 20:36

1 Answer 1

1
{"title"=>"DW1",
   "description"=>"DW1",
   "start_time"=>"2022-10-24 00:00",
   "end_time"=>"2022-10-28 00:00",
   "schedtimeranges_attributes"=>{"1666122012736"=>{"days"=>["1", "2", "3"], "start_time"=>"12:00 PM", "end_time"=>"6:00 PM", "_destroy"=>"false"}},
   "schedule_ids"=>["", "1", "2"]},

Based on your params, you will need an extra loop to iterate over days

  def create
    scheduleevent_params[:schedule_ids].each do |schedule_id|
      scheduleevent_params[:schedtimeranges_attributes].each do |key, value|
        value[:days].each do |day|
          @scheduleevent = Scheduleevent.new(scheduleinstid: schedule_id, day: day, title: scheduleevent_params[:title],
          description: scheduleevent_params[:description])
          @scheduleevent.user_id = current_user.id
          @scheduleevent.save
        end
      end
    end
  end
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks! This seems to be working without errors, but it is only creating one record. So if I select 2 schedule and have a sched time range that has 3 days of the week, I should have 6 records in the DB. It is only creating 1 record. Is that because I am redirecting after save? I have updated my original post with the full create event.
You are overwriting the same variable @scheduleevent and just calling save outside the loop. So it will just save the last schedule. You should call @scheduleevent.save inside the loop and then it will create 6 records.
@spacerobot if you found this answer helpful, please approve it. Thank you!
Gotcha. Thanks! I missed the save. It works now.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.