Rails 4 嵌套属性不保存
[英] Rails 4 nested attributes not saving
本文介绍了Rails 4 嵌套属性不保存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我似乎无法获取嵌套属性以保存到数据库.我正在使用 Rails 4.
这是我的模型:
class 答案 <ActiveRecord::Base归属地:问题结尾课堂问题<ActiveRecord::Basehas_many :answers归属地:调查accepts_nested_attributes_for :answers, allow_destroy: true结尾班级调查ActiveRecord::Basehas_many :问题validates_presence_of :nameaccepts_nested_attributes_for :questions结尾
这是控制器:
def 创建@survey = Survey.new(survey_params)response_to do |格式|如果@survey.saveformat.html { redirect_to @survey,注意:'调查已成功创建.'}format.json { 渲染动作:'show',状态::已创建,位置:@survey }别的format.html { 渲染动作:'新' }format.json { 渲染 json:@survey.errors,状态::unprocessable_entity }结尾结尾结尾定义调查参数params.require(:survey).permit(:name, questions_attributes:[:content, :id, :survey_id,answer_attributes:[:content, :id, :questions_id]])结尾
最后,这里是表单本身.我试过同时使用 f.fields_for 和只使用 fields_for
<%= form_for(@survey) do |f|%><% if @survey.errors.any?%><div id="error_explanation"><h2><%=pluralize(@survey.errors.count, "error") %>禁止保存此调查:</h2><ul><% @survey.errors.full_messages.each do |msg|%><li><%=msg%></li><%结束%>
<%结束%><div class="field"><%= f.label :name %><br><%= f.text_field :name %>
<%= 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 %><%结束%><%结束%><div class="actions"><%= f.submit %>
<%结束%>
调查好保存到数据库,问题和答案不会放.我查看了我能找到的所有资源,似乎我的做法是正确的,所以这真的让我发疯了.
这个例子只是一个快速的脚手架,所以我有一些代码要粘贴,但我似乎无法让它在其他任何地方工作.
将我的新操作更改为这样的内容:
def new@survey = Survey.new@survey.questions.build结尾
成功了!
请参阅 TEEGS 答案以获取解决方案
这是我使用的新表格,仍然只保存调查名称
<%= f.fields_for :question do |question_builder|%><%= form_for(@survey) 做 |f|%><% if @survey.errors.any?%><div id="error_explanation"><h2><%=pluralize(@survey.errors.count, "error") %>禁止保存此调查:</h2><ul><% @survey.errors.full_messages.each do |msg|%><li><%=msg%></li><%结束%>
<%结束%><div class="field"><%= f.label :name %><br><%= f.text_field :name %>
<%= 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 %><%结束%><%结束%><div class="actions"><%= f.submit %>
<%结束%>
解决方案
看起来您使用了错误的表单构建器对象.将问题部分更改为如下所示:
<%= 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 %><%结束%><%结束%>
最初您使用 f.fields_for :answers...
行中的 f
表单构建器,但是给定您的模型代码,因为它是一个 问题
accepts_nested_attributes_for
是Answer
,我们只需将表单构建器对象交换为用于question
部分的对象.
注意:为了清楚起见,我更改了构建器对象的名称.
更新
为了建立像这样的深度嵌套关系,您必须遍历构建"关联(在本例中为questions
),然后再次调用build
在它的 has_many
关联上.所以离开 gabrielhilal 的回答,你会这样做:
def new@survey = Survey.new@survey.questions.build@survey.questions.each 做 |问题|问题.答案.构建结尾结尾
注意,在您的情况下,由于您只明确创建一个问题,因此您可以在技术上改为执行此操作(而不是循环):
@survey.questions.first.answers.build
免责声明:如果有更干净、更符合 Rails 标准的方法来做到这一点,我很遗憾没有意识到.
I cannot seem to get nested attributes to save to the database. I am using Rails 4.
Here are my models :
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
Here is the controller:
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
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
WORKED!
SEE TEEGS ANSWER FOR SOLUTION TO THIS
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 %>
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.
Update
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
Disclaimer: If there is a cleaner, more Rails-y, way to do this, I am sadly unaware of it.
这篇关于Rails 4 嵌套属性不保存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文