嵌套模型表单 - 如果它尚不存在,如何通过关联创建对象?

时间:2011-03-29 00:41:18

标签: ruby-on-rails

来自Ryan Bates的episode about nested model forms,我能够创建一个他们玩concertsbandsperformances的项目。我可以在新的音乐会上或在我编辑音乐会时添加表演。当我按照他的教程时,这是相当简单和直接的。

performances属于bandsperformances属于concerts。演奏将列出乐队演奏和开始/结束的时间。乐队的名称只有一个字符串列。

当我创建一个新的音乐会并添加一大堆表演时,我同时能够创建band对象(如果它们尚不存在)。否则,用户具有创建这些对象的附加步骤,这将是乏味的。

如何通过accepts_nested_attributes_for或其他一些有用的Rails功能,我可以这样做吗?我正在使用Rails 2.3.8

以下是我的协会:

class Band < ActiveRecord::Base
  has_many :performances
  has_many :concerts, :through => :performances
end

class Concert < ActiveRecord::Base
  has_many :performances
  has_many :bands, :through => :performances
  accepts_nested_attributes_for :performances, :reject_if => lambda { |a| a[:content].blank? }, :allow_destroy => true
end

class Performance < ActiveRecord::Base
  belongs_to :band
  belongs_to :concert
end

3 个答案:

答案 0 :(得分:2)

Rails可以为你处理这个问题,你只需要确保以正确的方式传递参数(多个嵌套表单应该为你做)

class Concert < ActiveRecord::Base
  has_many :performances
  has_many :bands, :through => :performances

  accepts_nested_attributes_for :performances
end


class Performance < ActiveRecord::Base
  belongs_to :concert
  has_many :bands

  accepts_nested_attributes_for :bands
end


class Band < ActiveRecord::Base
  belongs_to :performance
end

您的params哈希应如下所示:

{
  :concert => {
    :performances_attributes => [
      {
        :bands_attributes => [
          {
            :name => "test u"
          }],
        :name=>"test p"
      }], 
    :name=>"test"
  }
}

答案 1 :(得分:0)

build要创建的关联的新空白实例。对于belongs_to,构建关联实例的方法是"build_#{association_name}",因此如果您想通过accepts_nested_attributes_for :band的性能创建一个新乐队,那么您将初始化一个空白乐队。控制器方法:

class PerformancesController < ApplicationController
  def new
    @performance = Performance.new       # You're building 
                                         # the performance to create
    @performance.build_band              # You're building
                                         # the band to create
  end
end

has_many关联的构建方法是"#{association_name}.build,因此对于accepts_nested_attributes_for :performances

的频段
class BandsController < ApplicationController
  def new
    @band = Band.new
    3.times { @band.performances.build }
  end
end

答案 2 :(得分:0)

您必须使用上面提到的构建方法才能在表单中显示字段。以下是您设置表单的方式。

<%= form_for @concert do |cf| %>  
  <%= cf.label :name %>  
  <%= cf.text_field :name %>  
  <%= cf.fields_for :performances do |pf| do %>  
     <%= pf.label :some_attr %>  
     ...  
     <%= pf.fields_for :bands do |bf| %>  
          <%= bf.label ... %>  
     <%end>  
  <% end %>  
<% end %>