Rails 4的嵌套属性不保存 [英] Rails 4 nested attributes not saving

查看:91
本文介绍了Rails 4的嵌套属性不保存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我似乎无法获取嵌套属性以保存到数据库.我正在使用Rails 4.

I cannot seem to get nested attributes to save to the database. I am using 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

Finally, here is the form itself. I have tried using both f.fields_for and just fields_for

<%= 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>

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

       <%= f.fields_for :answer do |builder| %>
         <%= builder.label :content, "Answer" %>
         <%= builder.text_field :content %>
       <% end %>

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

调查可以很好地保存到数据库中,而不会放置问题和答案.我已经查看了所有可以找到的资源,似乎我做得正确,所以这真的使我发疯.

The survey saves fine to the database, put the questions and answers will not. I've looked at every resource I could find and it seems like I am doing this correctly, so it's really driving me crazy.

这个示例只是一个快速的脚手架,所以我要粘贴一些代码,但似乎无法使其在其他任何地方都可以工作.

This example is just a quick scaffold so I had some code to paste in, but I can't seem to get it to work anywhere else.

将我的新操作更改为类似的:

edit: changing my new action to something like this:

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

工作!

请参阅解决方案

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

Here is the new form I am using, still only saving the survey name

  <%= f.fields_for :question do |question_builder| %>
  <%= 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>

  <%= 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 %>

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

推荐答案

好像您使用了错误的表单生成器对象.将问题部分更改为以下内容:

Looks like you're using the wrong form builder object. Change the question section to something like this:

<%= 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而不是accepts_nested_attributes_forAnswer,所以我们只需将表单生成器对象交换为question部分中使用的那个.

Originally you were using the f form builder in the line f.fields_for :answers..., however given your model code, since it is a Question that accepts_nested_attributes_for an Answer, we simply exchange the form builder object for the one used for the question section.

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

Note: I changed the names of the builder objects for clarity.

更新

为了建立这样一个深层嵌套的关系,您将必须遍历已建立"的关联(在本例中为questions),并再次在其has_many关联上调用build.因此,根据gabrielhilal的回答,您可以这样做:

In order to build a deeply nested relationship like this, you will have to loop through your "built" association (questions in this case), and invoke build again on its has_many association. So going off of gabrielhilal's answer, you would do this:

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

注意,在您的情况下,由于您仅明确创建了一个问题,因此从技术上讲,您可以这样做(而不是循环):

Note that in your case, since you are explicitly creating only one question, you can technically do this instead (instead of the loop):

@survey.questions.first.answers.build

免责声明::如果有一种更清洁,更Rails-y的方式来做到这一点,可悲的是我对此一无所知.

Disclaimer: If there is a cleaner, more Rails-y, way to do this, I am sadly unaware of it.

这篇关于Rails 4的嵌套属性不保存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆