如果有Some、Other兩個物件,若說Some擁有一個Other,可以如下定義:
has_one :other
end
則此時others表格中要有個some_id欄位作為外部鍵,參考至somes表格中的id主鍵。類似地,如果Some擁有多個Other,可以如下定義:
class Some < ActiveRecord::Base
has_many :others
end
則此時others表格中要有個some_id欄位作為外部鍵,參考至somes表格中的id主鍵。
如果希望Other被Some與Another共用,例如在一對一的情況:
class Some < ActiveRecord::Base
has_many :others
end
class Another < ActiveRecord::Base
has_many :others
end
那麼此時others表格中必須要有some_id與another_id,分別參考至somes表格與anothers表格的id,如果Other要被更多模型共用,更會形成欄位的浪費。
此時可以透過多型關聯方式,例如:
class Some < ActiveRecord::Base
has_many :others, :as => :owner # 我有許多other,而other會把我看成是owner
end
class Another < ActiveRecord::Base
has_many :others, :as => :owner # 我有許多other,而other會把我看成是owner
end
class Other < ActiveRecord::Base
belongs_to :owner, :polymorphic => true # 我屬於owner
end
如上指定之後,others中要有owner_id與owner_type兩個欄位,依照owner_type可得知owner_id是參考到somes或anothers的id,表格關係如下所示:
對於Some或Other實例而言,依舊是使用others方法取得關聯的資料。others表格的建立上,可以如下:
def change
create_table :others do |t|
t.string :name
t.integer :owner_id
t.string :owner_type
t.timestamps
end
end
end
也可簡化為:
def change
create_table :pictures do |t|
t.string :name
t.references :owner, :polymorphic => true
t.timestamps
end
end
end
一個具體的例子可在 A Guide to Active Record Associations 中 2.9 Polymorphic Associations 看到,將Picture作為Employee與Product共用的模型: