在模型级别上,您将使用accepts_nested_attributes_for。
class A < ApplicationModel
has_many :bs
accepts_nested_attributes_for :bs
validates_associated :bs
end
class B < ApplicationModel
belongs_to :a
end
这允许 A 获取属性并通过将属性 bs_attributes 与属性数组一起传递来创建嵌套的 bs。 validates_associated可以用来保证A不能持久化,bs也无效。
要创建nested form fields,请使用fields_for
<%= form_for(@a) do |f| %>
# field on A
<%= f.text_input :foo %>
# creates a fields for each B associated with A.
<%= f.fields_for(:bs) do |b| %>
<%= b.text_input :bar %>
<% end %>
<% end %>
对whitelist nested attributes 使用带有子记录允许属性数组的哈希键:
params.require(:a)
.permit(:foo, bs_attributes: [:id, :bar])
在创建新记录时,如果您希望存在用于创建嵌套记录的输入,您还必须“播种”表单:
class AsController < ApplicationController
def new
@a = A.new
seed_form
end
def create
@a = A.new(a_params)
if @a.save
redirect_to @a
else
seed_form
render :new
end
end
def update
if @a.update(a_params)
redirect_to @a
else
render :edit
end
end
private
def seed_form
5.times { @a.bs.new } if @a.bs.none?
end
def a_params
params.require(:a)
.permit(:foo, bs_attributes: [:id, :bar])
end
end
编辑:
seed_form 也可以只添加一个并且每次都这样做。所以你总是有一个“空”的要添加。如果没有填充,您需要确保在保存之前过滤掉空的,将accepts_nested_attributes_for更改为:
accepts_nested_attributes_for :bs, reject_if: proc { |attr| attr['bar'].blank? }