title: Rails -- how to populate parent object id using nested attributes for child object and strong parameters?
body: <p>I've got a situation much like is presented in <a href="http://railscasts.com/episodes/196-nested-model-form-part-1" rel="noreferrer">Railscast 196-197: Nested Model Form</a>.  However, I've encountered a conflict between this approach and strong parameters.  I can't figure out a good way to populate the parent record id field on the child object, since I don't want that to be assignable through the form (to prevent users from associating child records to parent records they don't own).  I have a solution (see code below) but this seems like the kind of thing Rails might have a clever, easy way to do for me.</p>
  
  <p>Here's the code...</p>
  
  <p>There's a parent object (call it Survey) that has_many child objects (call them Questions):</p>
  
  <pre><code># app/models/survey.rb
  class Survey
      belongs_to :user
      has_many :questions
      accepts_nested_attributes_for :questions
  end
  
  # app/models/question.rb
  class Question
      validates :survey_id, :presence =&gt; true
      belongs_to :survey
  end
  </code></pre>
  
  <p>There's a form that allows users to create a survey and the questions on that survey at the same time (for simplicity, the code below treats surveys as though they have only question):</p>
  
  <pre><code># app/views/surveys/edit.html.erb
  &lt;%= form_for @survey do |f| %&gt;
      &lt;%= f.label :name %&gt;
      &lt;%= f.text_field :name %&gt;&lt;br /&gt;
      &lt;%= f.fields_for :questions do |builder| %&gt;
          &lt;%= builder.label :content, "Question" %&gt;
          &lt;%= builder.text_area :content, :rows =&gt; 3 %&gt;&lt;br /&gt;
      &lt;% end %&gt;
      &lt;%= f.submit "Submit" %&gt;
  &lt;% end %&gt;
  </code></pre>
  
  <p>The problem is the controller.  I want to protect the survey_id field on the question record via strong parameters, but in doing so the questions don't pass validation, since the survey_id is a required field.</p>
  
  <pre><code># app/controllers/surveys_controller.rb
  class SurveysController
      def edit
          @survey = Survey.new
          Survey.questions.build
      end
  
      def create
          @survey = current_user.surveys.build(survey_params)
          if @survey.save
              redirect_to @survey
          else
              render :new
          end
      end
  
      private
  
      def survey_params
          params.require(:survey).permit(:name, :questions_attributes =&gt; [:content])
      end
  end
  </code></pre>
  
  <p>The only way I can think to solve this problem is to build the questions separately from the survey like this:</p>
  
  <pre><code>def create
      @survey = current_user.surveys.build(survey_params)
      if @survey.save
          if params[:survey][:questions_attributes]
              params[:survey][:questions_attributes].each_value do |q|
                  question_params = ActionController::Parameters.new(q)
                  @survey.questions.build(question_params.permit(:content))
              end
          end
          redirect_to @survey
      else
          render :new
      end
  end
  
  private
  
  def survey_params
      params.require(:survey).permit(:name)
  end
  </code></pre>
  
  <p>(Rails 4 beta 1, Ruby 2)</p>
  
  <p><strong>UPDATE</strong></p>
  
  <p>Perhaps the best way to handle this problem is to factor out a "Form object" as suggested in <a href="http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models/" rel="noreferrer">this Code Climate blog post</a>.  I'm leaving the question open, though, as I'm curious to other points of view</p>