Rails 4 - Nested models(2 levels) not saving

2019-08-15 14:16发布

问题:

Noob question on nested models.

I am using Rails 4 and trying to create nested models as below:

Survey has many questions Each Question has many answers

I am following Rails Casts episode #196 to create a survey, questions and answers in the same form. Surevey and Realted questions get saved but answers don't get saved to the database.(The answers fields however are being displayed right.)

I really appreciate your inputs on this.

Thanks, Mike

surveys_controller.rb

def index
   @surveys = Survey.all
end

def new
  @survey = Survey.new
  3.times do
    question = @survey.questions.build
    1.times { question.answers.build }
  end
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,answer_attributes:[:content]])
end

new.html.erb

<h1>New survey</h1>
  <%= render 'form' %>
<%= link_to 'Back', surveys_path %>

_form.html.erb:

<%= form_for(@survey) do |f| %>
   <% if @survey.errors.any? %>
      <div id="error_explanation">
          <h2><%= pluralize(@survey.errors.count, "error") %> prohibited this survey from being saved:</h2>
          <ul>
          <% @survey.errors.full_messages.each do |msg| %>
          <li><%= msg %></li>
          <% end %>
          </ul>
          </div>
   <%end%>

   <div class="field">
     <%= f.label :name %><br>
     <%= f.text_field :name %>
   </div>

   <!--Display Questions -->
   <%= f.fields_for :questions do |builder| %>
     <%= render 'question_fields', :f => builder%>
   <% end %>

   <div class="actions">
     <%= f.submit %>
   </div>

<% end %>

_questions_fields.html.erb:

<p>
 <%= f.label :content, "Question" %><br />
 <%= f.text_area :content, :rows => 3 %>
</p>

<!--Display Answers -->
<%=f.fields_for :answers do |builder| %>
   <p>
     <%= render 'answer_fields', :f => builder%>
   </p>
<%end%>

_answers_fields.html.erb:

<p>
 <%= f.label :content, "Answer" %>
 <%= f.text_field :content%>
</p>

Survey Model:

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

Question model:

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

Answer model:

  class Answer < ActiveRecord::Base
  belongs_to :question
  end

回答1:

Edit: Try changing answer_attributes to answers_attributes in the survey_params method.

Prying would have shown you that the answer attributes didn't get through.


After a quick look through I don't see anything particularly wrong, so you just need to debug. You should add gem 'pry-rails' to your Gemfile, then put

require 'pry'; binding.pry

on the line where you want to debug. I'd put it right before the save in your create action in the survey controller. Then submit the form and go to your server. It will be paused, and you will have a console. Type

@survey.save
@survey.errors

and see what comes up. Also type params and survey_params to make sure that your form data is all going through properly.

If you keep prying in different places you'll figure out what's not working. I suspect that your answers aren't being pulled into survey_params properly. Strong attributes is often the culprit when things aren't getting saved.