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

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

问题描述

我试图跟随瑞恩·贝茨 RailsCast#196:嵌套模型形成第1部分。 Ryans版本有两个明显的区别:1)我正在使用内置的脚手架,而不是漂亮,因为他正在使用,2)我正在运行rails 4(我不知道在他的演员中使用什么版本,但不是4)。



所以这里是我做的

  rails new survey2 
cd survey2
bundle install
rails生成脚手架调查名称:string
rake db:migrate
rails生成模型问题survey_id:整数内容:text
rake db:migrate

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

 类问题< ActiveRecord :: Base 
belongs_to:survey
end

 类调查< ActiveRecord :: Base 
has_many:questions
acceptance_nested_attributes_for:questions
end

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

 <%= form_for(@survey)do | f | %GT; 
<! - 标准导轨4查看内容 - >

< div class =field>
<%= f.label:name%>< br>
<%= f.text_field:name%>
< / div>
< div class =field>
<%= f.fields_for:questions do | builder | %GT;
< div>
<%= builder.label:content,问题%>< br />
<%= builder.text_area:content,:rows => 3%>
< / div>
<%end%>
< / div>
< div class =actions>
<%= f.submit%>
< / div>
<%end%>

最后控制器,以便每当新的调查被实例化时创建3个问题

  class SurveysController< ApplicationController 
before_action:set_survey只有:[:show,:edit,:update,,destroy]

#标准rails 4索引并显示

#GET /调查/新
def new
@survey = Survey.new
3.times {@ survey.questions.build}
Rails.logger.debug(新方法执行)
结束

#GET /考察/ 1 /编辑
def编辑
结束

#标准轨道4创建

#PATCH / PUT / survey / 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

#标准rails 4 destroy

private
#使用回调来共享动作之间的通用设置或约束。
def set_survey
@survey = Survey.find(params [:id])
end

#从不信任来自可怕互联网的参数,只允许白名单通过。
def survey_params
params.require(:survey).permit(:name,questions_attributes:[:content])
end
end

所以,用三个问题创建一个新的调查是可以的。但是,如果我尝试编辑其中一个调查,原来的三个问题将得到维护,另外还有三个问题被创建。所以我现在已经有6个问题了,我现在已经有6个了。我添加了

  Rails.logger.debug方法执行)

到控制器中的新方法,据我所知,它当我进行编辑操作时不执行。任何人都可以告诉我我在做错什么?



非常感谢任何帮助!

解决方案

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

 #不要信任来自可怕的互联网的参数,只允许白名单。 
def survey_params
params.require(:survey).permit(:name,questions_attributes:[:id,:content])
end
/ pre>

哪个工作完美。我是一个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天全站免登陆