Rails 4嵌套属性不保存

我似乎无法获得嵌套属性来保存到数据库。 我正在使用Rails 4。

这是我的模特:

class Answer < ActiveRecord::Base belongs_to :question end class Question < ActiveRecord::Base has_many :answers belongs_to :survey accepts_nested_attributes_for :answers, allow_destroy: true end class Survey < ActiveRecord::Base has_many :questions validates_presence_of :name accepts_nested_attributes_for :questions end 

这是控制器:

 def create @survey = Survey.new(survey_params) respond_to do |format| if @survey.save format.html { redirect_to @survey, notice: 'Survey was successfully created.' } format.json { render action: 'show', status: :created, location: @survey } else format.html { render action: 'new' } format.json { render json: @survey.errors, status: :unprocessable_entity } end end end def survey_params params.require(:survey).permit(:name, questions_attributes:[:content, :id, :survey_id, answers_attributes:[:content, :id, :questions_id] ]) end 

最后,这是表单本身。 我尝试过同时使用f.fields_for和fields_for

   

prohibited this survey from being saved:


该调查可以很好地保存数据库,不会提出问题和答案。 我看过我能找到的每一种资源,看起来我正确地做到了这一点,所以它真的让我发疯了。

这个例子只是一个快速的脚手架,所以我有一些代码要粘贴,但我似乎无法让它在其他任何地方工作。

编辑:将我的新动作更改为以下内容

 def new @survey = Survey.new @survey.questions.build end 

成功了!

请参阅解决方案以获得解决方案

这是我正在使用的新表单,仍然只保存调查名称

     

prohibited this survey from being saved:


看起来你正在使用错误的表单构建器对象。 将问题部分更改为以下内容:

 <%= f.fields_for :question do |question_builder| %> <%= question_builder.label :content %> <%= question_builder.text_area :content %> <%= question_builder.fields_for :answer do |answer_builder| %> <%= answer_builder.label :content, "Answer" %> <%= answer_builder.text_field :content %> <% end %> <% end %> 

最初你在f.fields_for :answers...行中使用f表单构建器,但是根据你的模型代码,因为它是一个Question一个AnswerQuestion ,我们只需交换用于question的表单构建器对象部分。

注意:为清楚起见,我更改了构建器对象的名称。

更新

为了构建这样的深层嵌套关系,你必须遍历你的“构建”关联(在这种情况下是questions ),并再次在其has_many关联上调用build 。 所以关闭gabrielhilal的答案,你会这样做:

 def new @survey = Survey.new @survey.questions.build @survey.questions.each do |question| question.answers.build end end 

请注意 ,在您的情况下,由于您只是明确地创建了一个问题,因此您可以在技术上改为(而不是循环):

 @survey.questions.first.answers.build 

免责声明:如果有更清洁,更多的Rails-y,这样做的方式,我很遗憾没有意识到这一点。

在你的控制器中你有questions_id

 def survey_params params.require(:survey).permit(:name, questions_attributes: [ :content, :id, :survey_id, answers_attributes: [:content, :id, :questions_id] ] ) end 

这是一个错字吗? 还可以尝试将action_on_unpermitted_parameters设置为:raise在您的development.rb :raise ,以查看您的survey_params方法中是否存在任何属性。

 # In case of unpermitted parameters in the controller raise error. config.action_controller.action_on_unpermitted_parameters = :raise 

您必须更改new操作以包含@survey.questions.build

 def new @survey = Survey.new @survey.questions.build end 

但你的forms也是错误的。 将question更改为questions

  <%= f.fields_for :questions do |builder| %> #questions <%= builder.label :content %> <%= builder.text_area :content %> 

你必须为答案做同样的事情。