title: Better way of handling complex form_for
body: <p>(this is a re-post - I deleted the first post because I think I posted really poorly).</p>
  
  <p>I'm new to programming, and I'm trying to handle an ROR form that sends data to 4 different models/tables, and at this point I'm banging my head into the wall. In sum, the use case is that a teacher inputs the following into a form: an error, a corresponding correction, an abstraction of the error, an abstraction of the correction, some tags that describe the abstraction, and an explanation. </p>
  
  <p>When I press submit, I'm not getting any errors on the screen, but when I look at the server, the only thing that gets submitted successfully is the original error and correction - I get an <code>unpermitted parameter: ec_abstractions</code> for the rest (ec_abstractions is the first level of nesting). I'm starting to think that I'm just going about the entire question wrongly.</p>
  
  <p>The form looks like this (maybe should be split into multiple forms on the same view page?)</p>
  
  <pre><code>&lt;%= form_for @ec_explanation do |ec_explanation_form| %&gt;
    &lt;% if @ec_explanation.errors.any? %&gt;
      &lt;div id="error_explanation"&gt;
        &lt;h2&gt;&lt;%= pluralize(@ec_explanation.errors.count, "error") %&gt; prohibited this error-correction pair from being saved:&lt;/h2&gt;
  
        &lt;ul&gt;
        &lt;% @ec_explanation.errors.full_messages.each do |message| %&gt;
          &lt;li&gt;&lt;%= message %&gt;&lt;/li&gt;
        &lt;% end %&gt;
        &lt;/ul&gt;
      &lt;/div&gt;
    &lt;% end %&gt;
  
    &lt;%#= Insert here: all (or a single) q_response(s) that have not yet been added %&gt;
  
    &lt;div class="field"&gt;
      &lt;%= ec_explanation_form.label :early_explanation %&gt;
      &lt;%= ec_explanation_form.text_area :early_explanation %&gt;
    &lt;/div&gt;
  
    &lt;div class="field"&gt;
      &lt;%= ec_explanation_form.label :full_explanation %&gt;
      &lt;%= ec_explanation_form.text_area :full_explanation %&gt;
    &lt;/div&gt;
      &lt;!--(this is just a test field for the "number_field" data type - I'm not convinced that we should input the stage like this)--&gt;
    &lt;div class="field"&gt;
      &lt;%#= ec_explanation_form.label :stage %&gt;
      &lt;%#= ec_explanation_form.number_field :stage %&gt;
    &lt;/div&gt;
  
      &lt;%= ec_explanation_form.fields_for :ec_abstractions do |ec_abstractions_form| %&gt;
  
          &lt;% if @ec_abstraction.errors.any? %&gt;
              &lt;div id="error_explanation"&gt;
                &lt;h2&gt;&lt;%= pluralize(@ec_abstraction.errors.count, "error") %&gt; prohibited this error-correction pair from being saved:&lt;/h2&gt;
  
                &lt;ul&gt;
                  &lt;% @ec_abstraction.errors.full_messages.each do |message| %&gt;
                      &lt;li&gt;&lt;%= message %&gt;&lt;/li&gt;
                  &lt;% end %&gt;
                &lt;/ul&gt;
              &lt;/div&gt;
          &lt;% end %&gt;
  
        &lt;div class="field"&gt;
          &lt;%= ec_abstractions_form.label :error_abstraction %&gt;
          &lt;%= ec_abstractions_form.text_field :error_abstraction %&gt;
        &lt;/div&gt;
  
        &lt;div class="field"&gt;
          &lt;%= ec_abstractions_form.label :correction_abstraction %&gt;
          &lt;%= ec_abstractions_form.text_field :correction_abstraction %&gt;
        &lt;/div&gt;
  
        &lt;%= ec_abstractions_form.fields_for :ec_pairs do |ec_pairs_form| %&gt;
  
          &lt;div class="field"&gt;
            &lt;%= ec_pairs_form.label :error_phrase %&gt;
            &lt;%= ec_pairs_form.text_field :error_phrase %&gt;
          &lt;/div&gt;
  
          &lt;div class="field"&gt;
            &lt;%= ec_pairs_form.label :correction_phrase %&gt;
            &lt;%= ec_pairs_form.text_field :correction_phrase %&gt;
          &lt;/div&gt;
  
          &lt;% end %&gt;
  
        &lt;%= ec_abstractions_form.fields_for :tags do |tags_form| %&gt;
  
          &lt;div class="field"&gt;
            &lt;%= tags_form.label :tag, "Tag" %&gt;
            &lt;%= tags_form.text_field :tag %&gt;
          &lt;/div&gt;
  
          &lt;div class="field"&gt;
            &lt;%= tags_form.label :tag, "Tag" %&gt;
            &lt;%= tags_form.text_field :tag %&gt;
          &lt;/div&gt;
  
          &lt;div class="field"&gt;
            &lt;%= tags_form.label :tag, "Tag" %&gt;
            &lt;%= tags_form.text_field :tag %&gt;
          &lt;/div&gt;
  
        &lt;% end %&gt;
      &lt;% end %&gt;
  
       (Include javascript (or bootstrap) that will generate extra tag fields onclick of a 'plus' button)
  
    &lt;div class="actions"&gt;
      &lt;%= ec_explanation_form.submit 'Submit Correction' %&gt;
    &lt;/div&gt;
  &lt;% end %&gt;
  </code></pre>
  
  <p>I have the following models:</p>
  
  <pre><code> class EcExplanation &lt; ApplicationRecord
        has_many :abstractions_explanations_joins
        has_many :ec_abstractions, :through =&gt; :abstractions_explanations_joins
        accepts_nested_attributes_for :abstractions_explanations_joins
      end
  
      class AbstractionsExplanationsJoin &lt; ApplicationRecord
        belongs_to :ec_explanation
        belongs_to :ec_abstraction
        accepts_nested_attributes_for :ec_abstraction
      end
  
      class EcAbstraction &lt; ApplicationRecord
        has_many :ec_pairs
        has_many :tags_ec_abstractions_joins
        has_many :tags, :through =&gt; :tags_ec_abstractions_joins
        has_many :abstractions_explanations_joins
        has_many :ec_explanations, :through =&gt; :abstractions_explanations_joins
        accepts_nested_attributes_for :tags_ec_abstractions_joins
        accepts_nested_attributes_for :ec_pairs
      end
  
      class EcPair &lt; ApplicationRecord
        belongs_to :response
        belongs_to :ec_abstraction
      end
  
      class TagsEcAbstractionsJoin &lt; ApplicationRecord
        belongs_to :ec_abstraction
        belongs_to :tag
        accepts_nested_attributes_for :tag, :reject_if =&gt; lambda { |a| a[:tag].blank? }
      end
  
      class Tag &lt; ApplicationRecord
        has_many :tags_ec_abstractions_joins
        has_many :ec_abstractions, :through =&gt; :tags_ec_abstractions_joins
      end
  </code></pre>
  
  <p>And the following controller code:</p>
  
  <pre><code>class CorrectionStoragesController &lt; ApplicationController
  
    def index
      @ec_explanations = EcExplanation.all
    end
  
    def show
    end
  
  
    def new
      @ec_explanation = EcExplanation.new
      @ec_abstraction = @ec_explanation.ec_abstractions.build
      @ec_pair = @ec_abstraction.ec_pairs.build
      3.times do
        @tag = @ec_abstraction.tags.build 
      end
    end
  
    def edit
    end
  
    def create
      @ec_explanation = EcExplanation.create(ec_explanation_params)
  
      respond_to do |format|
        if @ec_explanation.save
          format.html { redirect_to new_correction_storage_path, notice: 'Correction storage was successfully created.' }
          format.json { render :show, status: :created, location: @ec_explanation }
        else
          format.html { render :new }
          format.json { render json: @ec_explanation.errors, status: :unprocessable_entity }
        end
      end
    end
  
    def update
      respond_to do |format|
        if @ec_explanation.update(ec_explanation_params)
          format.html { redirect_to new_correction_storage_path, notice: 'Correction was successfully updated.' }
          format.json { render :show, status: :ok, location: new_correction_storage_path }
        else
          format.html { render :edit }
          format.json { render json: @ec_explanation.errors, status: :unprocessable_entity }
        end
      end
    end
  
    def destroy
      @ec_explanation.destroy
      respond_to do |format|
        format.html { redirect_to correction_storages_url, notice: 'Correction was successfully destroyed.' }
        format.json { head :no_content }
      end
    end
  
  
  
    private
  
      # Never trust parameters from the scary internet, only allow the white list through.
      def ec_explanation_params
        params.require(:ec_explanation).permit(:early_explanation, :full_explanation, ec_abstractions_attributes: [:id, :error_abstraction, :correction_abstraction, ec_pairs_attributes: [:id, :error_phrase, :correction_phrase], tags_attributes: [:id, :tag]])
      end
  end
  </code></pre>
  
  <p>Any help would be greatly appreciated. Thanks</p>