从父表单创建一定数量的子对象
感谢Ruby on Rails:如何从表单中收集子表的值? 和“Agile Web Dev”,我知道如何使用fields_for
在表单中fields_for
多个模型。 但是我正在撕掉我的头发。
假设我有一个模型Person
。 Person
有一个name
属性,并且has_many :foos
。 反过来, Foo
模型具有colour
属性。
而且,我知道每个Person
都有三个 Foos
。 我的模型, PersonController
的new
和create
操作以及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%> <%= label :colour, "Foo colour #{index + 1}: " %> <%= text_field("foo[]", "colour" %> <% end %>
<%= f.submit 'Create' %>
<% end %>
这似乎可以解决问题。