我有一堆“小孩”对象已经保存,我想创建一个父对象,通过“亲戚”模式链接到孩子.
这个对象给了我一对多,通过亲戚.
要明确:用户访问“父母”页面,点击创建父母,并提供一个表格,让他们命名父母,并加起来这个父母的四个孩子(通过创建“亲戚”),这些“关系” “也被命名 – 这是重要的一部分.所以,我可以命名关系“步子”或“儿子”.
以下是我到目前为止的代码:
class Kid < ActiveRecord::Base has_many :relatives has_many :parents,through: :relatives end class Parent < ActiveRecord::Base has_many :relatives has_many :kids,through: :relatives accepts_nested_attributes_for :relatives,:reject_if => lambda { |a| a[:content].blank? },:allow_destroy => true end class Relative < ActiveRecord::Base belongs_to :parent belongs_to :kid end class ParentsController < ApplicationController before_action :set_parent,only: [:show,:edit,:update,:destroy] before_action :lookup_kids,only: [:new,:edit] # GET /parents # GET /parents.json def index @parents = Parent.all end # GET /parents/1 # GET /parents/1.json def show end # GET /parents/new def new @parent = Parent.new 4.times { @parent.relatives.build } end # GET /parents/1/edit def edit end # POST /parents # POST /parents.json def create @parent = Parent.new(parent_params) parent_params[:relatives_attributes].each do |k,r| @parent.relatives.build(r.except(:_destroy)) end respond_to do |format| if @parent.save format.html { redirect_to @parent,notice: 'Parent was successfully created.' } format.json { render :show,status: :created,location: @parent } else format.html { render :new } format.json { render json: @parent.errors,status: :unprocessable_entity } end end end # cut for brevity. private # Use callbacks to share common setup or constraints between actions. def set_parent @parent = Parent.find(params[:id]) end def parent_params params.require(:parent).permit(:name,relatives_attributes: [:parent_id,:kid_id,:relationship,:_destroy]) end def lookup_kids @kids = Kid.all #for this nursery. end end <%= form_for(@parent) do |f| %> <% if @parent.errors.any? %> <div id="error_explanation"> <h2><%= pluralize(@parent.errors.count,"error") %> prohibited this parent from being saved:</h2> <ul> <% @parent.errors.full_messages.each do |message| %> <li><%= message %></li> <% end %> </ul> </div> <% end %> <div class="field"> <%= f.label :name %><br> <%= f.text_field :name %> </div> <h4>Kids:</h4> <%= f.fields_for :relatives do |r| %> <%= r.label :kid %> <%= r.collection_select :kid_id,@kids,:id,:name,include_blank: true%> <%= r.label :relationship %> <%= r.text_field :relationship %> <%= r.check_Box :_destroy %> <%= r.label :_destroy,"Remove" %> <br/> <% end %> <div class="actions"> <%= f.submit %> </div> <% end %> ActiveRecord::Schema.define(version: 20151030113634) do create_table "kids",force: :cascade do |t| t.string "name" t.datetime "created_at",null: false t.datetime "updated_at",null: false end create_table "parents",null: false end create_table "relatives",force: :cascade do |t| t.string "relationship" t.integer "parent_id" t.integer "kid_id" t.datetime "created_at",null: false end add_index "relatives",["kid_id"],name: "index_relatives_on_kid_id" add_index "relatives",["parent_id"],name: "index_relatives_on_parent_id" end
当我在父母控制器中“创建”时,我可以看到正确的参数正在通过,但关系记录没有被保存.这不会自动发生吗?
我尝试循环遍历:relatives_attributes,但似乎不适用于“build”.
我怎样才能让“亲戚”记录得到保存?
编辑:添加参数发布:
parent"=>{ "name"=>"Dad","relatives_attributes"=>{ "0"=>{"kid_id"=>"2","relationship"=>"Son","_destroy"=>"0"},"1"=>{"kid_id"=>"","relationship"=>"","2"=>{"kid_id"=>"","3"=>{"kid_id"=>"","_destroy"=>"0"}}}
编辑:我已经更新了,以显示我的最新编辑 – 注意’parent_params [:relatives_attributes] .each do | k,r |’在控制器中.这样现在可以保存孩子的记录,但唯一的问题是它也保存了空白的字段!所以我的“亲戚”记录为空值为孩子记录.我如何阻止它保存空字段(或创建空的相对记录)?
解决方法
答案是建立相对的每个子记录,如下所示:
parent_params[:relatives_attributes].each do |k,r| @parent.relatives.build(r.except(:_destroy)) end
在调用@ parent.save之前.
但是,我仍然有摆脱空白记录的问题.所以如果任何人有这个问题的答案,请在这里评论 – 或者如果有更好或更传统的做法,打我.跟进问题在这里:Why is this reject_if in my model not rejecting blank records?