从父窗体创建一定数量的子对象 [英] Creating a set number of child objects from a parent's form
问题描述
感谢 Ruby on Rails:如何从表单收集子表的值?和Agile Web Dev,I知道如何使用 fields_for
在表单中创建多个模型。但是我正在撕掉我的头发。
假设我有一个模型 Person
。 Person
具有名称
属性,并且 has_many:foos
。 Foo
模型反过来具有颜色
属性。
此外,我知道每个 另外,我可以做到这一点没有 在玩过方形大括号和不同循环的不同位置后,我想我解决了这个问题。这是我的代码现在的样子(根据脚手架设置路线,以便从 models / person.rb models / foo.rb controllers / people_controller.rb views / people / new.html.erb 这似乎是个窍门。 Thanks to Ruby on Rails: How to gather values for child tables from a form? and "Agile Web Dev", I know how to have multiple models in a form using Suppose I have a model Furthermore, I know that each Also, can I do this without After some playing about with varied locations for square braces and different for loops, I think I've solved this. Here's what my code looks like now (with routes set up as per scaffolding, so that posting from models/person.rb models/foo.rb controllers/people_controller.rb views/people/new.html.erb This seems to do the trick. 这篇关于从父窗体创建一定数量的子对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋! Person
都有正好三个 Foos
。我的模型, new
和在
PersonController
>和新
视图看起来像是为了呈现三个标记为好的文本输入框,每个Foo一个,并且能够报告验证错误,以允许我的新人的形式来创建一整套四个对象?
acceptersted_attributes_for
? / new
>触发 create
)。
class Person< ActiveRecord :: Base
has_many:foos
validates_presence_of:name
end
class Foo< ActiveRecord :: Base
belongs_to:person
validates_presence_of:color
validates_uniqueness_of:color,:scope => person_id
end
def new
#设置一个有3个默认Foos的人
@person = Person.new
(1..3 ).each {| i | @ person.foos.build}
结束
def创建
#创建(但不保存)指定的人
@person = Person.new( params [:person])
#为每组Foo细节创建(但不保存)Foo
@foos = []
params [:foo]。每个都做| foo_param |
@foos<< Foo.new(foo_param)
结束
#在交易中保存所有内容
Person.transaction do
@ person.save!
@ foos.each do | foo |
foo.person = @person
foo.save!
结束
结束
redirect_to:action => 'show',:id => @person
rescue ActiveRecord :: RecordInvalid => e
@ foos.each do | foo |
foo.valid?
结束
render:action => 'new'
end
<%form_for:person do | f | %GT;
<%= error_messages_for:object => [@person] + @ person.foos%>
< p>
<%= f.label:name%>< br />
<%= f.text_field:name%>
< / p>
< table>
<%@ person.foos.each_with_index do | foo,index | @foo = foo%>
< tr>
< td><%= label:color,Foo color#{index + 1}:%>< / td>
< td><%= text_field(foo [],color%>< / td>
< / tr>
<%end%> ;
< / table>
< p>
<%= f.submit'创建'%>
< / p>
<%end%>>
fields_for
. But I'm tearing my hair out over this one.Person
. Person
has a name
attribute, and has_many :foos
. The Foo
model, in turn, has a colour
attribute.Person
has precisely three Foos
. What should my Models, the new
and create
actions in PersonController
, and the new
view look like in order to present three nicely-labelled text-entry boxes, one for each Foo and capable of reporting validation errors, to allow my "new person" form to create the whole set of four objects in one go?accepts_nested_attributes_for
?/new
triggers create
).class Person < ActiveRecord::Base
has_many :foos
validates_presence_of :name
end
class Foo < ActiveRecord::Base
belongs_to :person
validates_presence_of :colour
validates_uniqueness_of :colour, :scope => "person_id"
end
def new
# Set up a Person with 3 defaulted Foos
@person = Person.new
(1..3).each { |i| @person.foos.build }
end
def create
# Create (but don't save) a Person as specified
@person = Person.new(params[:person])
# Create (but don't save) a Foo for each set of Foo details
@foos = []
params[:foo].each do |foo_param|
@foos << Foo.new(foo_param)
end
# Save everything in a transaction
Person.transaction do
@person.save!
@foos.each do |foo|
foo.person = @person
foo.save!
end
end
redirect_to :action => 'show', :id => @person
rescue ActiveRecord::RecordInvalid => e
@foos.each do |foo|
foo.valid?
end
render :action => 'new'
end
<% form_for :person do |f| %>
<%= error_messages_for :object => [@person] + @person.foos %>
<p>
<%= f.label :name %><br />
<%= f.text_field :name %>
</p>
<table>
<% @person.foos.each_with_index do |foo, index| @foo = foo%>
<tr>
<td><%= label :colour, "Foo colour #{index + 1}: " %></td>
<td><%= text_field("foo[]", "colour" %></td>
</tr>
<% end %>
</table>
<p>
<%= f.submit 'Create' %>
</p>
<% end %>