RoR 嵌套属性在编辑时会产生重复项 [英] RoR nested attributes produces duplicates when edit

查看:10
本文介绍了RoR 嵌套属性在编辑时会产生重复项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试关注 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屋!

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