2011-04-11 79 views
2

我有以下型號協會:accepts_nested_attributes_for和二階協會,嵌套形式

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與slip一起保存,所以我在< - > slip之間有一個參考。有了這個設置,我放棄了參考。我可以獲得所有關聯的客戶,但是我會得到與訂單相關的客戶的所有相關單據。


這裏我的模型的字段: 訂單 - > ID
客戶 - > ID
嘉賓 - > ID,ORDER_ID,CUSTOMER_ID
滑 - > ID,ORDER_ID,CUSTOMER_ID


訂單的結果應該看起來像這樣

  • 爲了
    1. 客戶A
      • 滑1
      • 滑2
    2. 客戶B
      • 滑1
      • 滑2
    3. 客戶A
      • 滑1
      • 滑2
      • 滑3

我不知道如何做到這一點。

+0

我可以想象如何爲存在@order,但對於新秩序它是非常複雜的。你可以在這裏使用old school虛擬屬性來嵌套資源,但不能使用現代accept_nested_attributes_for' – fl00r 2011-04-11 14:03:07

+0

也許有一個鉤子,我可以將order_id傳遞給滑動模型? – wdbmh 2011-04-11 15:38:40

+0

我已添加評論來解釋解決方案 – fl00r 2011-04-11 16:42:35

回答

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。這只是關於理解一種方法。

UPD您的ID衝突。這只是一個scetch

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 
+0

完美,這對我有效,雖然我不得不改變: customers.each {| c | C [:slips_attributes]。每個{| S | s [:order_id] = @ order.id}} 至 customers.values.each {| c | C [:slips_attributes] .values.each {| S | s [:order_id] = @ order.id}} – wdbmh 2011-04-11 18:52:46

+0

不是一個大的修正:D很樂意幫助 – fl00r 2011-04-11 18:56:07

+0

現在清理你的控制器並乾燥你的方法。刪除所有這些東西到模型:) – fl00r 2011-04-11 18:56:58