上回我們講到 Active Record Association 的基礎觀念,今天繼續延伸下去!
Polymorphic Association 多型關聯
多型關聯(Polymorphic Association)是一種在資料庫中建立關聯的方法,允許一個模型與多個其他模型建立關聯,並且可以根據需要動態指向這些模型中的一個。主要目的是在不知道或不確定關聯到哪個模型的情況下實現關聯。
想像你正在建立一個簡單的網站,用戶可以發表評論(Comments),但這些評論可以關聯到多種不同類型的內容,例如文章(Articles)和圖片(Photos)。這時就可以使用多型關聯。
建立一個
Comment
模型,該模型將關聯到多種不同類型的內容。1
2
3class Comment < ApplicationRecord
belongs_to :commentable, polymorphic: true
end建立其他模型,例如
Article
和Photo
,並將它們與Comment
進行多型關聯。1
2
3
4
5
6
7class Article < ApplicationRecord
has_many :comments, as: :commentable
end
class Photo < ApplicationRecord
has_many :comments, as: :commentable
end
我們就可以在 Comment
模型中使用 commentable
來關聯到不同類型的內容。
例如,當用戶發表一個評論時:
1 | # 建立一個評論關聯到一篇文章 |
可以通過 commentable
關聯動態地關聯到不同類型的內容,同時保持代碼的簡單性和可擴展性。
Self-joining Associations 自連接關聯
自連接(Self-joining)關聯是一種在資料庫中建立關聯的技術,其中同一個表格(或模型)中的記錄可以與該表格中的其他記錄建立關聯。換句話說,就是在一個模型中創建一個與自己相關聯的關聯,通常用於處理與模型自身相關的數據。
例如,有一個 “Employee” 的模型,每個員工都有一個直接上級(即另一個員工),並且他們都屬於同一個公司。
可以使用自連接來建立員工之間的關聯,同時維護每個員工的直接上級。
1 | # Employee 模型 |
這個模型有兩個關聯:
belongs_to :manager
:這個關聯表示每個員工都屬於另一個員工,並且class_name
參數指定了關聯的模型是自身的 “Employee” 模型。意即,每個員工都有一個直接上級,但不是每個員工都必須有一個直接上級(所以我們使用optional: true
)。has_many :subordinates
:這個關聯表示每個員工都可以擁有多個下屬,同樣,我們使用class_name
和foreign_key
參數指定了關聯的模型和外鍵字段。
使用這些關聯來建立員工之間的關係:
1 | # 建立員工記錄 |
這樣,你可以使用自連接來建立模型內部的層次結構關係,這在處理組織結構、層次性數據或任何需要記錄與自身建立關聯的情況下非常有用。自連接使用相同的模型在內部建立關聯,同時保持代碼的簡潔性和可讀性。
補充觀念
在 Rails Guide - Active Record Association 中,有提及關於在 Rails 應用程式中有效使用 Active Record Association 的注意事項:
控制緩存(Controlling caching):
Active Record 通常會對關聯數據進行緩存,以提高性能。
一些查詢結果可能會被緩存在記憶體中,但有時這可能導致意外的行為。
可以使用reload
方法來重新加載關聯數據,以確保獲取的是最新的數據。避免名稱衝突(Avoiding name collisions):
在模型中定義多個關聯時,要注意避免名稱衝突!
如果多個關聯使用相同的名稱,可能會導致混淆和錯誤。
為每個關聯選擇具有描述性的名稱,並使用:class_name
選項來指定模型的名稱,以避免混淆。更新模式(Updating the schema):
更改模型之間的關聯時,記得更新 schema!
如果新增、刪除或修改關聯,需要遷移(migration)來更新資料庫結構,以反映新的關聯。控制關聯範圍(Controlling association scope):
使用
has_many
或has_one
關聯時,可以使用:scope
選項來定義範圍,以限制關聯中的數據。這對於過濾或排序關聯數據非常有用。雙向關聯(Bi-directional associations):
有時可能需要在兩個模型之間建立雙向關聯,也就是說,當一個模型關聯到另一個模型時,也希望反向的關聯也存在。這可以通過在兩個模型中分別定義關聯來實現。確保處理好雙向關聯可以更方便地訪問和操作數據。
參考資料:
➫ Polymorphic Association
➫ PJCHENder - [Rails] Active Record Association (Model)