次の行に沿って何かを試すことができます。
class Account < ActiveRecord::Base
belongs_to :corp_or_gov_customer, :polymorphic => true
def account_id
self.id
end
end
class GovernmentCustomer < ActiveRecord::Base
has_one :account, :as => :corp_or_gov_customer, :dependent => :destroy
def method_missing( symbol, *args )
self.account.send( symbol, *args )
end
end
class CorporateCustomer < ActiveRecord::Base
has_one :account, :as => :corp_or_gov_customer, :dependent => :destroy
belongs_to :priv_or_pub_customer, :polymorphic => true
def method_missing( symbol, *args )
self.account.send( symbol, *args )
end
end
class PrivateCustomer < ActiveRecord::Base
has_one :corporate_customer, :as => :priv_or_pub_customer, :dependent => :destroy
def method_missing( symbol, *args )
self.corporate_customer.send( symbol, *args )
end
end
class PublicCustomer < ActiveRecord::Base
has_one :corporate_customer, :as => :priv_or_pub_customer, :dependent => :destroy
def method_missing( symbol, *args )
self.corporate_customer.send( symbol, *args )
end
end
私はこのコードをテストしていません (または構文をチェックしていません)。むしろ、ポリモーフィックな関係の方向性を示すことだけを目的としています。
ネストされたオブジェクトを呼び出すために method_missing をオーバーライドすると、次のようなコードを書く必要がなくなります
my_public_customer.corporate_customer.account.some_attribute
代わりに、あなたはただ書くことができます
my_public_customer.some_attribute
コメントに応えて:
問題は、「ある」、「多数ある」、「所属する」などの概念がすべて、リレーショナル モデルの外部キー関係によって実装されていることです。継承の概念は、RDB システムとはまったく異なります。これらの関係のセマンティクスは、選択した ORM テクノロジによってリレーショナル モデルにマッピングする必要があります。
しかし、Rails の ActiveRecord ライブラリは、モデル間の関係として「is_a」を実装していません。
RDB でクラス階層をモデル化するには、いくつかの方法があります。
すべてのアカウント用の単一のテーブルですが、冗長な属性があります。これは、テーブルに「タイプ」列を追加するだけで ActiveRecord によってサポートされます。次に、次のようにクラス階層を作成します。
class Account < ActiveRecord::Base
class GovernmentCustomer < Account
class CorporateCustomer < Account
class PublicCustomer < CorporateCustomer
class PrivateCustomer < CorporateCustomer
その後、PrivateCustomer.new を呼び出すと、type フィールドは自動的に「PrivateCustomer」に設定され、Account.find を呼び出すと、返されるオブジェクトは正しいクラスになります。
これは、あなたが望むことを行うための最も簡単な方法であるため、私がお勧めするアプローチです。
具象クラスごとに 1 つのテーブル- 私が知る限り、ActiveRecord ではこれに対するマッピングは提供されていません。この方法の主な問題は、すべてのアカウントのリストを取得するには、3 つのテーブルを結合する必要があることです。必要なのは、次のモデルにつながる何らかのマスター インデックスです。
クラスごとに 1 つのテーブル- 抽象クラスを表すテーブルは、一種の統一インデックス、または具象クラスのテーブルに格納されているオブジェクトのカタログと考えることができます。このように考えることで、is_a 関係を has_a 関係に変更することになります。これは、多態的な関係を使用して ActiveRecord によってマッピングできます。
この問題については、書籍「Agile Web Development with Rails」 (第 2 版の 341 ページから) で非常によく説明されています。