0

주문 양식이 있으며 주문이 생성되면 새로운 고객도 생성됩니다. 내가 가진 내 OrderController에서레일 4 중첩 된 양식, 1 모델 연관 ID 없음

= simple_form_for(@order) do |f| 
    = render 'order_fields', f: f 
    = f.simple_fields_for :subscriptions do |subscription| 
     = render 'subscription_fields', subscription: subscription 
    = f.simple_fields_for :customer do |customer| 
     = render 'customer_fields', customer: customer 
    = f.button :submit 

: :이 양식을 가지고

class Customer < ActiveRecord::Base 
    has_many :orders 
    has_many :subscriptions, through: orders 
end 

class Order < ActiveRecord::Base 
    belongs_to :customer 
    has_many :subscriptions 

    accepts_nested_attributes_for :customer 
    accepts_nested_attributes_for :subscriptions 
end 

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

내 주문 페이지 :

def new 
    @order = Order.new 
    @order.build_customer 
    @order.subscriptions.build 
end 

def create 
    @order = Order.new(order_params) 

    if @order.save  
     (.... etc ...) 
end 

private 
    def order_params 
     params.require(:order).permit(
      :amount, 
      customer_attributes: [ :id, :email, :password, :password_confirmation], 
      subscriptions_attributes: [ :id, :product_id, :customer_id]) 
    end 

는 거의 모든 것이 잘 진행이 들어 나는 다음과 같은 모델을 가지고
- 사용자가 생성되었습니다.
- 주문이 생성되고 customer_id = User.id가됩니다.
- 구독이 생성되고 ORDER_ID있다 = Order.id

그러나 어떻게 든 늘 고객 :(
내가 가진 계속에 가입을 연결 Subscription.customer_id = 전무

수있는 사람하시기 바랍니다 올바른 방향으로 나를 가리켜 주시겠습니까? 모델에 문제가 있습니까? 또는 컨트롤러에서? 나는 더 이상 볼 곳이 없다.

답변

1

귀하의 관계가 약간 다르게 설정되었습니다. 서브 스크립 션에 customer_id 필드를 생성하는 대신 has_one :customer, through: :order을 갖기를 기대합니다.

이렇게하면 더 이상 구독 모델에 customer_id 속성이 필요하지 않습니다. 구독의 세계관에서 고객의 ID를 원하면 subscription.customer.id으로 전화하십시오.

모델에서 관계에 대해 inverse_of 지정을 추가 할 수도 있습니다 (데이터베이스에서 모델을 다시로드하는 것을 최소화하는 것이 좋습니다).

class Customer < ActiveRecord::Base 
    has_many :orders, inverse_of: :customer 
    has_many :subscriptions, through: orders 
end 

class Order < ActiveRecord::Base 
    belongs_to :customer, inverse_of: :orders 
    has_many :subscriptions, inverse_of: :order 

    accepts_nested_attributes_for :customer 
    accepts_nested_attributes_for :subscriptions 
end 

class Subscription< ActiveRecord::Base 
    belongs_to :order, inverse_of: :subscriptions 
    has_one :customer, through: :order # THIS IS THE KEY CHANGE 
end 

아, 그리고 당신은 subscriptions_attributes을 위해 허용 된 속성으로부터 customer_id을 제거 할 수 있습니다

그래서, 총, 나는 권하고 싶습니다.

UPDATE

구독 번호의 CUSTOMER_ID가 고객으로부터 끊긴하기위한 것입니다 점을 감안 -> 주문 -> 구독 관계가 ... (아마 inverse_of 물건 제외) 이상을 무시하고 ... 당신을 할 수 있어야합니다 :

class Customer < ActiveRecord::Base 
    has_many :subscriptions, through: :orders, after_add: :cache_customer_id 

    private 

    def cache_customer_id(subscription) 
    subscription.update_column(:customer_id, self.id) 
    end 
end 
+0

pdobb. 한순간에 일하고 있으며 고객의 기권을 얻을 수 있습니다. 그러나이 방법은 내가 다른 고객에게 구독을 옮기고 싶을 때 문제가된다. (가능한 것이어야한다.) 내 아이디어는 구독에 고객 레퍼런스가있을 때, 나는 쉽게 고객 ID를 변경하여 구독을 다른 고객에게 옮길 수있다. 이제 주문을 다른 고객에게 이전해야합니까 (아니겠습니까?). 주문이 원래 고객과 연결되어 있어야하기 때문에 맞지 않을 것입니다. – Jerry

+0

이해합니다. 이 경우 구독 객체에서 customer_id를 설정하는 고객에게 구독을 추가 할 때'after_add' 콜백을 사용할 수 있습니다. 나는 이것을 보여줄 나의 대답을 업데이트 할 것이다. – pdobb

+0

두 번째 시도해 주셔서 감사합니다. :) 업데이트를 시도했지만 구독 모델에 customer_id를 추가하지 않았습니다. 그리고 그것이 작동해야한다면, 이는 모든 "Customer.create"에서 구독 모델이 업데이트되고 관리자가 주문이나 구독없이 새로운 고객을 만들 수 있도록 유연해야한다는 것을 의미합니다. 그래서 기본적으로 필요한 것은 Order.create 후에 customer_id를 추가하는 함수입니다. 나는 after_add를 order.model에서 시도해 보았고 (self.id를 self.customer.id로 바꿨다.) 그러나 잘못된 수의 인자 (1은 0)를 준다. – Jerry

0

감사합니다 pdobb! 나는 그것을 order.controller에 추가하는 것으로 지금 일하고있다. :

def create 
    @order = Order.new(order_params) 

    if @order.save  
     @order.subscriptions.each { subscription| subscription.update_column(:customer_id, @order.customer.id) } 
end