2011-04-11 2 views
2

내가 단체와 모델을 다음 있습니다 :accepts_nested_attributes_for 및 2 차 협회, 중첩 된 형태

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 슬립으로 저장해야합니다, 그래서 주문 < 사이의 참조가> 미끄러 져. 이 설정으로 참조가 느슨합니다. 모든 관련 고객을 확보 할 수는 있지만 주문과 관련된 고객의 모든 관련 전표를받습니다. 내 모델 여기


분야 : 주문 -> 아이디
고객 -> ID
고객 -> ID, ORDER_ID,
슬립 CUSTOMER_ID -> ID를, ORDER_ID, CUSTOMER_ID


주문 결과는 다음과 같아야합니다.

  • 주문
    1. 고객
      • 슬립 1
      • 슬립 2
    2. 고객 B
      • 슬립 1
      • 슬립 2
    3. 고객
      • 슬립 1
      • 슬립 2
      • 슬립 3

나는이 작업을 수행하는 방법을 아무 생각도 없어.

+0

나는 어떻게 해야할지 상상할 수 있지만, 새로운 주문의 경우 매우 복잡합니다.중첩 된 리소스에 오래된 학교 가상 속성을 사용할 수 있지만 여기에는 현대적인 'accepts_nested_attributes_for'가 없습니다. – fl00r

+0

slip_id에 order_id를 전달할 수있는 고리가 있습니까? – wdbmh

+0

솔루션을 설명하는 데 의견을 추가했습니다. – fl00r

답변

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

완벽해야합니다. 변경해야했지만 완벽했습니다. customers.each {| c | c [: slips_attributes] .each {| s | s [: order_id] = @ order.id}} ~ customers.values.each {| c | c [: slips_attributes] .values.each {| s | s [: order_id] = @ order.id}} 큰 수정이 아닌 – wdbmh

+0

: D 도움이되어 기쁩니다 – fl00r

+0

이제 컨트롤러를 청소하고 메서드를 건조하십시오. 이 모든 것을 모델로 제거하십시오 :) – fl00r

관련 문제