RoR 嵌套属性在编辑时会产生重复项 [英] RoR nested attributes produces duplicates when edit
问题描述
我正在尝试关注 Ryan Bates RailsCast #196:嵌套模型形成第 1 部分.Ryans 版本有两个明显的区别:1)我使用的是内置脚手架,不像他使用的那样漂亮,2)我正在运行 rails 4(我真的不知道 Ryans 在他的演员阵容中使用的是什么版本,但不是 4).
这就是我所做的
rails 新调查2光盘调查2捆绑安装rails 生成脚手架调查名称:字符串耙分贝:迁移rails 生成模型问题survey_id:整数内容:文本耙分贝:迁移
然后我像这样将关联添加到模型中
类问题 <活动记录::基础属于:调查结尾
等等
类调查 <活动记录::基础has_many :问题接受嵌套属性:问题结尾
然后我添加了嵌套视图部分
<%= form_for(@survey) 做 |f|%><!-- 标准导轨 4 查看内容 --><div 类="字段"><%= f.label :name %><br><%= f.text_field :name %></div><div 类="字段"><%= f.fields_for :questions do |builder|%><%= builder.label :content, "问题" %><br/><%= builder.text_area :content, :rows =>3%></div><%结束%></div><div 类="动作"><%= f.submit %></div><%结束%>最后是控制器,以便在实例化新调查时创建 3 个问题
类 SurveysController <应用控制器before_action :set_survey,仅:[:show, :edit, :update, :destroy]# 标准 rails 4 索引和显示# 获取/调查/新定义新@survey = Survey.new3.times {@survey.questions.build}Rails.logger.debug("新方法执行")结尾# 获取/调查/1/编辑定义编辑结尾# 标准导轨 4 创建# PATCH/PUT/调查/1# PATCH/PUT/surveys/1.json定义更新respond_to 做 |格式|如果@survey.update(survey_params)format.html { redirect_to @survey, notice: '调查已成功更新.'}format.json { 头 :no_content }别的format.html { 渲染动作:'编辑' }format.json { 渲染 json:@survey.errors,状态::unprocessable_entity }结尾结尾结尾# 标准铁轨 4 销毁私人的# 使用回调在动作之间共享通用设置或约束.def set_survey@survey = Survey.find(params[:id])结尾# 永远不要相信来自可怕互联网的参数,只允许白名单通过.def 调查参数params.require(:survey).permit(:name, questions_attributes: [:content])结尾结尾
因此,创建一个包含三个问题的新调查就可以了.但是,如果我尝试编辑其中一项调查,则会保留原来的三个问题,同时还会创建另外三个问题.因此,我现在有 6 个问题,而不是编辑后的调查问卷的 3 个问题.我添加了
Rails.logger.debug("新方法执行")
到控制器中的新方法,据我所知,当我进行编辑操作时它不会执行.谁能告诉我我做错了什么?
非常感谢任何帮助!
解决方案 所以我想通了.我必须在 survey_params
方法中将 :id
添加到允许的参数中.现在看起来像这样:
# 永远不要相信来自可怕互联网的参数,只允许白名单通过.def 调查参数params.require(:survey).permit(:name, questions_attributes: [:id, :content])结尾
效果很好.我是 RoR 新手,所以请对我的分析持保留态度,但我想新的 id 是在哪里生成的,而不是被传递给更新操作.希望这对其他人有帮助.
I'm trying to follow Ryan Bates RailsCast #196: Nested model form part 1. There're two apparent differences to Ryans version: 1) I'm using built-in scaffolding and not nifty as he's using, and 2) I'm running rails 4 (I don't really know what version Ryans using in his cast, but it's not 4).
So here's what I did
rails new survey2
cd survey2
bundle install
rails generate scaffold survey name:string
rake db:migrate
rails generate model question survey_id:integer content:text
rake db:migrate
Then I added the associations to the models like so
class Question < ActiveRecord::Base
belongs_to :survey
end
and so
class Survey < ActiveRecord::Base
has_many :questions
accepts_nested_attributes_for :questions
end
Then I added the nested view part
<%= form_for(@survey) do |f| %>
<!-- Standard rails 4 view stuff -->
<div class="field">
<%= f.label :name %><br>
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.fields_for :questions do |builder| %>
<div>
<%= builder.label :content, "Question" %><br/>
<%= builder.text_area :content, :rows => 3 %>
</div>
<% end %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
and finally the controller so that 3 questions are created whenever a new survey is instantiated
class SurveysController < ApplicationController
before_action :set_survey, only: [:show, :edit, :update, :destroy]
# Standard rails 4 index and show
# GET /surveys/new
def new
@survey = Survey.new
3.times { @survey.questions.build }
Rails.logger.debug("New method executed")
end
# GET /surveys/1/edit
def edit
end
# Standard rails 4 create
# PATCH/PUT /surveys/1
# PATCH/PUT /surveys/1.json
def update
respond_to do |format|
if @survey.update(survey_params)
format.html { redirect_to @survey, notice: 'Survey was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: @survey.errors, status: :unprocessable_entity }
end
end
end
# Standard rails 4 destroy
private
# Use callbacks to share common setup or constraints between actions.
def set_survey
@survey = Survey.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def survey_params
params.require(:survey).permit(:name, questions_attributes: [:content])
end
end
So, creating a new survey with three questions is fine. However, if I try to edit one of the surveys, the original three questions are maintained, while an additional three more are created. So instead of having 3 questions for the edited survey, I now have 6. I added
Rails.logger.debug("New method executed")
to the new method in the controller, and as far as I can tell, it is not executed when I'm doing an edit operation. Can anyone tell me what I'm doing wrong?
Any help is greatly appreciated!
解决方案 So I figured it out. I had to add :id
to the permitted params in the survey_params
method. It now looks like this:
# Never trust parameters from the scary internet, only allow the white list through.
def survey_params
params.require(:survey).permit(:name, questions_attributes: [:id, :content])
end
which works perfectly. I'm a RoR newbie, so please take my analysis of this with a grain of salt, but I guess that new id's where generated instead of being passed to the update action. Hope this helps someone else out there.
这篇关于RoR 嵌套属性在编辑时会产生重复项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文