从父表单创建一定数量的子对象

感谢Ruby on Rails:如何从表单中收集子表的值? 和“Agile Web Dev”,我知道如何使用fields_for在表单中fields_for多个模型。 但是我正在撕掉我的头发。

假设我有一个模型PersonPerson有一个name属性,并且has_many :foos 。 反过来, Foo模型具有colour属性。

而且,我知道每个Person都有三个 Foos 。 我的模型, PersonControllernewcreate操作以及new视图应该是什么样子,以便呈现三个标记良好的文本输入框,每个Foo一个并且能够报告validation错误,以允许我的“新人”表单一次创建整个四个对象?

另外,如果没有accepts_nested_attributes_for ,我可以这样accepts_nested_attributes_for吗?

在一些人玩各种各样的方形括号和不同的循环之后,我想我已经解决了这个问题。 这是我的代码现在的样子(根据脚手架设置路由,以便从/new触发器create )。

车型/ person.rb

 class Person < ActiveRecord::Base has_many :foos validates_presence_of :name end 

车型/ foo.rb

 class Foo < ActiveRecord::Base belongs_to :person validates_presence_of :colour validates_uniqueness_of :colour, :scope => "person_id" end 

控制器/ people_controller.rb

 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 

意见/人/ new.html.erb

 <% form_for :person do |f| %> <%= error_messages_for :object => [@person] + @person.foos %> 

<%= f.label :name %>
<%= f.text_field :name %>

<% @person.foos.each_with_index do |foo, index| @foo = foo%> <% end %>
<%= label :colour, "Foo colour #{index + 1}: " %> <%= text_field("foo[]", "colour" %>

<%= f.submit 'Create' %>

<% end %>

这似乎可以解决问题。