accepts_nested_attributes_for和二阶关联,嵌套表单

时间:2011-04-11 13:29:30

标签: ruby-on-rails nested-forms nested-attributes

我有以下关联模型:

class Order < ActiveRecord::Base
  has_many :guests
  has_many :customers, :through => :guests
  accepts_nested_attributes_for :customers
end

class Customer < ActiveRecord::Base
   has_many :guests
   has_many :orders, :through => :guests
   has_many :slips
   accepts_nested_attributes_for :slips
end

class Slip < ActiveRecord::Base
   belongs_to :order
   belongs_to :customer
end

class Guest < ActiveRecord::Base
  belongs_to :order
  belongs_to :customer
end

我的嵌套表单如下所示:

<!-- general form -->
<%= form_for(@order) do |f| %>
    <% f.fields_for :customers do |builder| %>
        <%= render "customer_fields", :f => builder %>
    <% end %>
    <%= f.submit %>
<% end %>

<!-- partial customer_fields -->
<p>
    <%= f.label :name%><%= f.text_field :name %>
    <% f.fields_for :slips do |builder| %>
        <%= render "slip_fields", :f => builder %>
    <% end %>
</p>

<!-- partial slip_fields -->
<p><%= f.label :quantity%><%= f.text_field :quantity %></p>

使用此设置保存订单按预期工作,但我需要使用单据保存order_id,因此我在订单&lt; - &gt;之间有一个参考。滑。通过这种设置,我放松了参考。我可以获得所有相关客户,但我会得到客户与订单相关的所有相关单据。


这里是我模特的领域: 订单 - &gt; ID
客户 - &gt; ID
访客 - &gt; id,order_id,customer_id
滑动 - &gt; id,order_id,customer_id


订单的结果应如下所示

  • 订单
    1. 客户A.
      • Slip 1
      • Slip 2
    2. 客户B
      • Slip 1
      • Slip 2
    3. 客户A.
      • Slip 1
      • Slip 2
      • Slip 3

我不知道如何做到这一点。

1 个答案:

答案 0 :(得分:1)

如果你不能为不存在的订单返回order_id,你可以执行此挂钩(我没有测试它,所以你可能需要修复它)

def create
  customers = params[:order].delete :customers_attributes
  @order = Order.new params[:order]
  if @order.save
    customers.each{|c| c[:slips_attributes].each{|s| s[:order_id] = @order.id} }
    @order.customers_attributes = customers
    @order.save
  end
end

def update
  @order = Order.find params[:id]
  params[:order][:customers_attributes].each{|c| c[:slips_attributes].each{|s| s[:order_id] = @order.id} }
  @order = Order.update_attributes params[:order]
  @order.save
end

另外,您最好将所有这些逻辑移到模型中,然后dry可以稍微进行一下。这只是为了理解一种方法。

您的ID冲突的

UPD 。这只是一个昙花一现

def create
  customers = params[:order].delete :customers_attributes
  @order = Order.new params[:order]
  @order.customer_ids = customers.inject([]){|a,h| a << h[:b] if h[:b]; a}
  if @order.save
    customers.each{|c| c[:slips_attributes].each{|s| s[:order_id] = @order.id} }
    @order.customers_attributes = customers
    @order.save
  end
end

def update
  @order = Order.find params[:id]
  @order.customer_ids = params[:order][:customers_attributes].inject([]){|a,h| a << h[:b] if h[:b]; a}
  params[:order][:customers_attributes].each{|c| c[:slips_attributes].each{|s| s[:order_id] = @order.id} }
  @order = Order.update_attributes params[:order]
  @order.save
end