I've successfully been able to implement this tutorial up to a point.
I can get the nested items to appear by saving the parent form and going back to edit, but I am unable to get my Delete or my Add Option button to actually work.
The Delete button doesn't appear to actually do anything and I can't understand the server stream to figure out what it is trying to do.
The Add Option button somehow is returning "unpermitted parameter" for :title, :description, :question_options_attributes error by attempting to create a parent record instead of a child one as it goes up one level in the controller chain to the surveys/questions_controller#create action.
here's what I have so far:
class SurveyQuestion < ApplicationRecord
  belongs_to :survey_section
  has_many :question_options
  accepts_nested_attributes_for :question_options, reject_if: :all_blank, allow_destroy: true
class Surveys::QuestionsController < SurveysController
    before_action :get_section, only: [:index, :new, :create, :update, :edit]
    before_action :set_question, only: [:edit, :update]
    ...
    def edit
        @option = @question.options.build
        render partial: "surveys/questions/edit", locals: {q: @question, 
            survey: @survey, section: @section, option: @option}
    end
     private
        def get_section
            @survey = Survey.find_by(slug: params[:survey_slug])
            @section = @survey.sections.find_by(section_number: params[:sec_num])
        end
        def create_params
            params.require(:survey_question).permit(:survey_section_id, :position, :question_type)
        end
        def update_params
            params.require(:survey_question).permit(:survey_setion_id, :position, :question_type, 
                :title, :description, question_options_attributes: [:id, :_destroy, :name, 
                    :logic, :sub_logic])
        end
        
        def set_question
            @question = @section.questions.find_by(position: params[:position])
        end
In my survey question edit view:
%turbo-frame{id: "question_#{q.id}", data: {turbo: {action: "advance"}}}
    = form_with(model: q, url: survey_question_path(survey_slug: survey.slug, position: q.position, sec_num: section.section_number)) do |f|
     ...
      %turbo-frame{id: "options"}
        = f.fields_for :question_options, q.options do |of|
            = render "surveys/questions/options/form", form: of, q: q
    .text-start
        = f.submit "Add Option", formaction: survey_question_option_path(survey_slug: q.survey_section.survey.slug, question_position: q.position, index: q.options.size, sec_num: q.survey_section.section_number), formmethod: :post, formnovalidate: true, id: "add_option"
in the surveys/questions/options/form partial:
%turbo-frame{id: "question_#{q.id}_option_#{form.index}"}
    = form.hidden_field :id
    %p This is form index number #{form.index}.
    .form-floating.mb-4
        = form.text_field :name, placeholder: "Option #{form.index + 1}", class: "form-control border border-dark"
        = form.label :name, "Option #{form.index + 1}"
    = form.submit "Delete", formaction: survey_question_option_path(survey_slug: q.survey_section.survey.slug, question_position: q.position, index: form.index, id: form.object.id, sec_num: q.survey_section.section_number), formmethod: :delete, formnovalidate: true, data: {turbo: {frame: "question_#{q.id}_option_#{form.index}"}}
in the surveys/questions/options/create.turbo_stream.haml:
= fields model: @question do |f|
  = f.fields_for :question_options, @options, child_index: params[:index] do |of|
    = turbo_stream.replace "add_option" do
      = f.submit "Add Option", formaction: survey_question_option_path(survey_slug: @survey.slug, question_position: @question.position, index: of.index.to_i + 1, sec_num: @section.section_number), formmethod: :post, formnovalidate: true, id: "add_option"
    = turbo_stream.append "options" do
      = render "surveys/questions/options/form", form: task_form, q: @question
in the surveys/questions/options/destroy.turbo_stream.haml partial:
= fields model: @question do |f|
    = f.fields_for :question_options, @options, child_index: params[:index] do |of|
        %turbo-frame{id: "question_#{@question.id}_option_#{of.index}"}
            = of.hidden_field :id, value: params[:id]
            = of.hidden_field :_destroy, value: true
= turbo_stream.remove(id: "question_#{@question.id}_option_#{params[:index]}")
the options controller:
class Surveys::Questions::OptionsController < Surveys::QuestionsController
    before_action :setup
    def new
    end
    def destroy
    end
    private
        def setup
            @survey = Survey.find_by(slug: params[:survey_slug])
            @channel = @survey.channel
            @section = @survey.sections.find_by(section_number: params[:sec_num])
            @question = @section.questions.find_by(position: params[:question_position])
            @options = @question.options
        end
end
And finally the relevant routes:
   resources :surveys, param: :slug do
      resources :sections, controller: "surveys/sections", param: :sec_num
      resources :questions, controller: "surveys/questions", param: :position do
        resources :options, controller: "surveys/questions/options", only: [], param: :index do
          member do
            delete "(:id)" => "surveys/questions/options#destroy", as: ""
            post "/" => "surveys/questions/options#create"
          end
        end
      end
    end
Did I miss something?
 
    