你可以嘗試大意如下的東西。
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類型字段將自動設置爲「PrivateCustomer」,當你調用Account.find返回的對象將是一個正確的類。
這是我推薦的方法,因爲它是迄今爲止最簡單的方法來做你想做的事。
每個具體類的一個表 - 據我所知在ActiveRecord中沒有爲此提供映射。這種方法的主要問題是,要獲得所有帳戶的列表,您必須加入三個表。需要的是某種主索引,這導致了下一個模型。
每個類的一張表 - 您可以將表示抽象類的表視爲一種統一索引,或存儲在具體類的表中的對象的目錄。通過這種方式思考它,你正在將is_a關係改變爲has_a關係,例如對象has_a index_entry和index_entry屬於對象。這可以通過使用多態關係的ActiveRecord進行映射。
出現這個問題的書中"Agile Web Development with Rails"(在第2版起341頁)
如果帳戶/ CoroprateCustomer是一個抽象類,一個很好的討論,它真的需要一個表? – Swanand 2009-06-19 15:50:52
我相信如此。我改變了實體名稱,以使它們不具有域特定性(如果以下內容有點人爲的話,請原諒我)。 CorporateCustomers有1:M的關係,政府客戶不。例如,公司客戶可以有許多財務報表。因爲我不想要GovCustomers有這種關係,所以我把表格分開,所以我的FinancialStatement表格可以在CorpCustomers上FK。 – 2009-06-19 16:04:06
此外,所有3個實體(私人,公共和政府)共享相同的PK ID空間。因此私人和政府客戶不可能擁有1的PK。賬戶表確保。在這種情況下你會認爲這些表格是需要的嗎? – 2009-06-19 16:04:47