Ruby on rails 如何从父控制器保存子记录?
我已经保存了一堆“孩子”对象,我想创建一个通过“相对”模型链接到孩子的父对象 这个物体通过亲戚给了我很多很多 需要明确的是:用户访问“家长”页面,单击“创建家长”,并显示一个表单,允许他们命名家长,并将最多四个孩子添加到此家长(通过创建“亲属”),每个“关系”也被命名,这是一个重要部分。例如,我可以将这种关系命名为“继子”或“子” 以下是我目前掌握的代码:Ruby on rails 如何从父控制器保存子记录?,ruby-on-rails,Ruby On Rails,我已经保存了一堆“孩子”对象,我想创建一个通过“相对”模型链接到孩子的父对象 这个物体通过亲戚给了我很多很多 需要明确的是:用户访问“家长”页面,单击“创建家长”,并显示一个表单,允许他们命名家长,并将最多四个孩子添加到此家长(通过创建“亲属”),每个“关系”也被命名,这是一个重要部分。例如,我可以将这种关系命名为“继子”或“子” 以下是我目前掌握的代码: class Kid < ActiveRecord::Base has_many :relatives has_many :pa
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", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", 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
t.datetime "updated_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
Edit:我已更新此项以显示我的最新编辑-请注意“parent_params[:relatives_attributes]。控制器中的每个do | k,r |”。这现在保存了kid记录,但唯一的问题是,它还保存了空白字段!所以我有“相对”记录,其中kid记录的值为空。如何停止保存空字段(或创建空的相对记录)?根据表单提交的方式,您很可能还需要相对关联类中的accepts_nested_属性:
class Relative
belongs_to :parent
accepts_nested_attributes_for :parent
belongs_to :kid
accepts_nested_attributes_for :kid
end
如果这不起作用,那么请提交传递到控制器中的参数,我们可以相应地调整答案是构建relative的每个子记录,如下所示:
parent_params[:relatives_attributes].each do |k,r|
@parent.relatives.build(r.except(:_destroy))
end
在呼叫@parent.save之前
但是,我仍然有摆脱空白记录的问题。因此,如果有人对这个问题有答案,请在这里发表评论——或者如果有更好或更传统的方法,请联系我。接下来的问题是:正如我所说,我已经保存了一堆“kid”对象,所以我不需要在Relative上为kid添加嵌套的accepts\u。我正在parents控制器中创建Relative,因此我也不需要为parents嵌套—它的工作方式正好相反(post to parents控制器中包含的Relative数据,嵌套)。我将在上面的问题中添加发布到控制器的参数。谢谢。不过为了彻底起见,我确实试过这个,但它没有改变任何东西。“孩子”的记录都没有保存。注意,在上面的例子中,只有一个孩子被填写为家长。这是故意的-它应该忽略空格。请从创建操作中删除父参数[:亲戚属性]。每个…内容。之后,如果保存时收到
COMMIT
或ROLLBACK
,请检查控制台。如果有回滚,只需添加put@parent.errors.full_消息。在呈现错误之前检查,并检查控制台。如果您有提交功能,请检查控制台中是否有未经许可的属性(但我认为这是正确的,您将找不到)。它会提交。控制台上没有未经允许的参数警告。但是,它不会在家长上保存“亲属”(我在rails控制台中查看了记录)。哦,我读了标题如何从家长控制器保存我的孩子记录?
,并认为这是从另一个stackexchange站点发来的,在那里,家长正在询问他们孩子在学校或幼儿园的记录!
parent_params[:relatives_attributes].each do |k,r|
@parent.relatives.build(r.except(:_destroy))
end