Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unpermitted parameters for double-nested models in Rails 4

I'm new to Rails and built something based on this, but it needed small updates to make it compatible with Rails 4's strong parameters:

http://railscasts.com/episodes/196-nested-model-form-part-1

I whitelisted the parameters for the survey, questions and answers based on a similar post here:

Rails 4 Nested Attributes Unpermitted Parameters

class Survey < ActiveRecord::Base
  has_many :questions, :dependent => :destroy
  accepts_nested_attributes_for :questions, allow_destroy: true
end

class Question < ActiveRecord::Base
  belongs_to :survey
  has_many :answers, :dependent => :destroy
  accepts_nested_attributes_for :answers, allow_destroy: true
end

class Answer < ActiveRecord::Base
  belongs_to :question
end

class SurveysController < ApplicationController
  def survey_params
    params.require(:survey).permit(:name, questions_attributes: [:id, :survey_id, :content])
  end

class QuestionsController < ApplicationController
  def question_params
    params.require(:question).permit(:survey_id, :content, answers_attributes: [:id, :question_id, :content])
  end

class AnswersController < ApplicationController
  def answer_params
    params.require(:answer).permit(:question_id, :content)
  end

The first nested model (Question) works, but the second (Answer) returns an error when I submit the main survey form:

Unpermitted parameters: answers_attributes

Started POST "/surveys" for 127.0.0.1 at 2013-07-10 19:20:00 +0800
Processing by SurveysController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"pCK7j73kJPmld6gMXtbnBcheHU3pb9FGdjbHJPX6leE=", "survey"=>{"name"=>"test", "questions_attributes"=>{"0"=>{"content"=>"bbb", "answers_attributes"=>{"0"=>{"content"=>"bbbb"}}}}}, "commit"=>"Create Survey"}
Unpermitted parameters: answers_attributes

I checked the database and the data isn't there, and found the error in the log. The first set of nested data (the questions) are there and working, it's only the second next that isn't. I also have the :id in there that people say you need too.

As far as I know, each parent needs to whitelist the direct nested attribute it will modify. I used exactly the same code to get questions to work, but answers aren't being whitelisted even though I have done so in questions.

Any pointers appreciated. I can't seem to find any double-nested examples to look at.

UPDATE: I fixed the issue by trial and error.

I found out the fix is that the whitelist needs to match the nesting of attributes. So to fix the above I changed this:

class SurveysController < ApplicationController
  def survey_params
    params.require(:survey).permit(:name, questions_attributes: [:id, :survey_id,    :content])
  end

to this:

class SurveysController < ApplicationController
  def survey_params
    params.require(:survey).permit(:name, questions_attributes: [:id, :survey_id,    :content, answers_attributes: [:id, :question_id, :content]])
  end

E.g. simply copy the whitelist of the answers_attributes and insert it inside before the closing "]" for the questions_attributes.

like image 929
mr.b Avatar asked Jul 10 '13 11:07

mr.b


1 Answers

I found out the fix is that the whitelist needs to match the nesting of attributes. So to fix the above I changed this:

class SurveysController < ApplicationController
  def survey_params
    params.require(:survey).permit(:name, questions_attributes: [:id, :survey_id,    :content])
  end

to this:

class SurveysController < ApplicationController
  def survey_params
    params.require(:survey).permit(:name, questions_attributes: [:id, :survey_id,    :content, answers_attributes: [:id, :question_id, :content]])
  end

E.g. simply copy the whitelist of the answers_attributes and insert it inside before the closing "]" for the questions_attributes.

Hopefully this will help others with the same problem.

like image 81
mr.b Avatar answered Nov 13 '22 07:11

mr.b