2017-03-21 15 views
0

私が取り組んでいるアプリケーションでは、多態性を使用せずに多態性の概念を使用しようとしています。カスタムbelongs_to属性ライター

class User 
has_many :notes 
end 

class Customer 
has_many :notes 
end 

class Note 
belongs_to :user 
belongs_to :customer 
end 

は本質的に、我々はノート上に2つの列があります。user_idcustomer_idは、今ここに悪いことはノートが今customer_idと私はしたくない同時にuser_idを持つことが可能ですです。

私は単純な/より良いアプローチは、ノートテーブルを多態性にすることを知っていますが、私はそれを今からやめさせるいくつかの制限があります。

これらの関連付けをオーバーライドするカスタム方法があるかどうかを知りたいのですが、割り当てが割り当てられているときにもう一方が割り当てられていないことを確認します。使用しているとき

note.customer=customer or 
note.update(customer: customer) 

が、動作します:

def user_id=(id) 
    super 
    write_attribute('customer_id', nil) 
end 

def customer_id=(id) 
    super 
    write_attribute('user_id', nil) 
end 

これは動作しません使用している場合:ここで

は、私が試したものです

note.update(customer_id: 12) 

私は基本的に必要4つの方法を書かなくても、両方のケースで機能するもの:

def user_id=(id) 

end 

def customer_id=(id) 

end 

def customer=(id) 

end 

def user=(id) 

end 

答えて

1

このような結果を得るには、むしろActiveRecordコールバックを使用します。

class Note 

    belongs_to :user 
    belongs_to :customer 

    before_save :correct_assignment 

    # ... your code ... 

    private 

    def correct_assignment 
    if user_changed? 
     self.customer = nil 
    elsif customer_changed? 
     self.user = nil 
    end 
    end 

end 
+0

ありがとう。その問題は、レコードを永続化する前に、私は一度に2つの州のレコードを持っていたので、私は 'before_save:do_something_to_owner'のようなものを持っていれば、現在2つの州が存在し、コールバックは悪いです。もう1つのバグ領域は両方のフィールドを一度に更新することになります。これは最初のブランチにフォールバックして、フィールドをnilにしか更新しないと仮定して、引き続き引数を再度チェックする必要があります。しかし、良い解決策のように思えますが、後でもっとバグがあると思います。私はここに明白に行くと思う – oreoluwa