RoR:「またはもう一方」がありますか?(または、継承を持たないポリモーフィズム。)
-
22-08-2019 - |
質問
皆さん、私のプロジェクトには興味深い要件があります。私は〜が必要です has_one
どちらかのクラスであるが、継承がない関係。それが唯一の方法であれば、継承を回避することもできますが、2 つの関連付けられたレコードは完全に異なるデータを持ち、まったく関連性がありません。
私が理解する必要があるのは、次のようなことです。
# 1. Foo never belongs to anything.
# 2. Foo MUST have one assigned sub-record for validity.
# 3. Foo can only have either Bar or Baz assigned.
# 4. Bar and Baz have only ONE common property, and aren't
# related in either data or implementation.
class Foo < ActiveRecord::Base
# Attributes: id, name, value
has_one :assignment, :foreign_key => 'assigned_to', :readonly => true
# Could really use an :object_type for has_one here...
end
class Bar < ActiveRecord::Base
# Attributes: name,...
end
class Baz < ActiveRecord::Base
# Attributes: name,...
end
どこ Foo
次のいずれかのタイプの割り当てが 1 つあります Bar
または Baz
;共通の列は 1 つだけ共有しているので、そこから親オブジェクトを作成できるかもしれません。ただし、それらを共通オブジェクトから継承させる場合 (含まれるデータが実際にはオレンジとリンゴの場合)、レコード用のテーブルを作成する必要がありますか?記録が抽象的な記録であっても、子供たちはそうではない場合、おそらくそれを回避できるでしょうか?
もう私の難しさがおわかりいただけると思います。私は RoR についてはかなり初心者ですが、これまでのところ大好きです。これを回避する方法はあると思いますが、それが何であるかを理解できなかったら、私はがっかりします。
解決
リレーショナル データベースのパラダイムに適合しないものをモデル化しようとしています。SQL のすべての参照には、起点とターゲットが 1 つずつあります。
FWIW、ポリモーフィック アソシエーションも、このルールに違反するため、アンチパターンです。壊れたデザインであることを示す手がかりとなるはずです。 ドキュメンテーション 参照整合性制約を機能させるには、参照整合性制約を省略する必要があると言います。
2つ持つにはFooが必要です has_one
人間関係:1人はバーに、もう1人はバズに。次に、いくつかのクラス ロジックを実装して、Foo のインスタンスに参照が 1 つだけ設定されるようにします。つまり、Bar と Baz への参照のうち、1 つは値を持つ必要があり、もう 1 つは nil である必要がありますが、これはコードでチェックして強制する必要があります。
他のヒント
おそらく一つの方法は、バーやバズのために、Fooの中で、持っているものに関連付けを作成することです。その後、バーやバズにアクセスするための唯一の方法することができます割り当てと割り当てと呼ばれるメソッドを作成します=。あなたは、getメソッドでnilでない2 has_onesのどのチェックし、その1を返すことができます。割り当て方法では、渡された変数の型が何であるかを、確認することができ、そのオブジェクトへの正しいが、持っている1の関係を設定し、nilに他を設定します。それはあまりにも複雑されることなく、すべての拠点をカバーするべきである。