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

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

问题描述

我正在尝试关注 Ryan Bates RailsCast #196:嵌套模型形成第 1 部分.Ryans 版本有两个明显的不同:1)我使用的是内置脚手架,而不是他使用的漂亮,2)我正在运行 rails 4(我真的不知道 Ryans 在他的演员中使用的是什么版本),但不是 4).

这就是我所做的

rails 新的调查2光盘调查2捆绑安装rails 生成脚手架调查名称:字符串耙数据库:迁移rails 生成模型问题survey_id:integer content:text耙数据库:迁移

然后我像这样将关联添加到模型中

类问题

等等

班级调查

然后我添加了嵌套视图部分

<%= form_for(@survey) do |f|%><!-- 标准导轨 4 视图内容--><div class="field"><%= f.label :name %><br><%= f.text_field :name %>

<div class="field"><%= f.fields_for :questions do |builder|%><div><%= builder.label :content, "问题" %><br/><%= builder.text_area :content, :rows =>3%>

<%结束%>

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

<%结束%>

最后是控制器,以便在实例化新调查时创建 3 个问题

class SurveysController <应用控制器before_action :set_survey, only: [:show, :edit, :update, :destroy]# 标准导轨 4 索引和显示# 获取/调查/新定义新@survey = Survey.new3.times { @survey.questions.build }Rails.logger.debug("新方法执行")结尾# GET/surveys/1/edit定义编辑结尾# 标准导轨 4 创建# PATCH/PUT/surveys/1# PATCH/PUT/surveys/1.json定义更新response_to do |格式|如果@survey.update(survey_params)format.html { redirect_to @survey,注意:'调查已成功更新.'}format.json { 头:no_content }别的format.html { 渲染动作:'编辑' }format.json { 渲染 json:@survey.errors,状态::unprocessable_entity }结尾结尾结尾# 标准导轨 4 销毁私人的# 使用回调在动作之间共享公共设置或约束.def set_survey@survey = Survey.find(params[:id])结尾# 永远不要相信来自可怕互联网的参数,只允许白名单通过.定义调查参数params.require(:survey).permit(:name, questions_attributes: [:content])结尾结尾

因此,创建一个包含三个问题的新调查没问题.但是,如果我尝试编辑其中一个调查,则会保留原来的三个问题,同时创建另外三个问题.因此,我现在有 6 个问题,而不是 3 个问题用于编辑后的调查.我添加了

Rails.logger.debug("新方法执行")

到控制器中的新方法,据我所知,它在我进行编辑操作时不会执行.谁能告诉我我做错了什么?

非常感谢任何帮助!

解决方案

所以我想通了.我必须将 :id 添加到 survey_params 方法中允许的参数中.现在看起来像这样:

# 永远不要相信来自可怕互联网的参数,只允许白名单通过.定义调查参数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天全站免登陆