### [](https://octobercms.com/docs/database/relations#polymorphic-relations)多態關系
多態關系允許一個模型在單個關聯上屬于多個以上的模型。
### [](https://octobercms.com/docs/database/relations#one-to-one-polymorphic-relations)一對一
#### 表結構
一對一的多態關系類似于簡單的一對一關系。但是,目標模型可以在單個關聯上屬于一種以上類型的模型。例如,假設您要存儲員工和產品的照片。使用多態關系,您可以`photos`在這兩種情況下使用一個表。首先,讓我們檢查建立這種關系所需的表結構:
~~~
staff
id - integer
name - string
products
id - integer
price - integer
photos
id - integer
path - string
imageable_id - integer
imageable_type - string
~~~
需要注意的兩個重要列是表中的`imageable_id`和`imageable_type`列`photos`。該`imageable_id`列將包含擁有人員或產品的ID值,而該`imageable_type`列將包含擁有模型的類名。該`imageable_type`列是ORM如何確定訪問該`imageable`關系時要返回的擁有模型的“類型”。
#### 模型結構
接下來,讓我們檢查建立這種關系所需的模型定義:
~~~
class Photo extends Model
{
public $morphTo = [
'imageable' => []
];
}
class Staff extends Model
{
public $morphOne = [
'photo' => ['Acme\Blog\Models\Photo', 'name' => 'imageable']
];
}
class Product extends Model
{
public $morphOne = [
'photo' => ['Acme\Blog\Models\Photo', 'name' => 'imageable']
];
}
~~~
#### 檢索多態關系
定義數據庫表和模型后,您可以通過模型訪問關系。例如,要訪問工作人員的照片,我們可以簡單地使用`photo`dynamic屬性:
~~~
$staff = Staff::find(1);
$photo = $staff->photo
~~~
您還可以通過訪問`morphTo`關系名稱來從多態模型中檢索該多態關系的所有者。在我們的例子中,這就是模型的`imageable`定義`Photo`。因此,我們將其作為動態屬性進行訪問:
~~~
$photo = Photo::find(1);
$imageable = $photo->imageable;
~~~
在`imageable`對關系`Photo`模式將返回一個`Staff`或`Product`實例,這取決于模型的類型擁有的照片。
### [](https://octobercms.com/docs/database/relations#one-to-many-polymorphic-relations)一對多
#### 表結構
一對多多態關系類似于簡單的一對多關系。但是,目標模型可以在單個關聯上屬于一種以上類型的模型。例如,假設您的應用程序的用戶可以“評論”帖子和視頻。使用多態關系,您可以`comments`在這兩種情況下使用一個表。首先,讓我們檢查建立這種關系所需的表結構:
~~~
posts
id - integer
title - string
body - text
videos
id - integer
title - string
url - string
comments
id - integer
body - text
commentable_id - integer
commentable_type - string
~~~
#### 模型結構
接下來,讓我們檢查建立這種關系所需的模型定義:
~~~
class Comment extends Model
{
public $morphTo = [
'commentable' => []
];
}
class Post extends Model
{
public $morphMany = [
'comments' => ['Acme\Blog\Models\Comment', 'name' => 'commentable']
];
}
class Product extends Model
{
public $morphMany = [
'comments' => ['Acme\Blog\Models\Comment', 'name' => 'commentable']
];
}
~~~
#### 檢索關系
定義數據庫表和模型后,您可以通過模型訪問關系。例如,要訪問帖子的所有評論,我們可以使用`comments`dynamic屬性:
~~~
$post = Author\Plugin\Models\Post::find(1);
foreach ($post->comments as $comment) {
//
}
~~~
您還可以通過訪問`morphTo`關系名稱來從多態模型中檢索該多態關系的所有者。在我們的例子中,這就是模型的`commentable`定義`Comment`。因此,我們將其作為動態屬性進行訪問:
~~~
$comment = Author\Plugin\Models\Comment::find(1);
$commentable = $comment->commentable;
~~~
在`commentable`對關系`Comment`模式將返回一個`Post`或`Video`實例,這取決于模型的類型擁有評論。
您還可以通過將屬性設置為`morphTo`關系的名稱(在本例中為)來更新相關模型的所有者`commentable`。
~~~
$comment = Author\Plugin\Models\Comment::find(1);
$video = Author\Plugin\Models\Video::find(1);
$comment->commentable = $video;
$comment->save()
~~~
### [](https://octobercms.com/docs/database/relations#many-to-many-polymorphic-relations)多對多
#### 表結構
除了“一對一”和“一對多”關系外,您還可以定義“多對多”多態關系。例如,博客`Post`和`Video`模型可以共享與模型的多態關系`Tag`。使用多對多多態關系使您可以擁有一個唯一標簽列表,該列表在博客文章和視頻之間共享。首先,讓我們檢查表結構:
~~~
posts
id - integer
name - string
videos
id - integer
name - string
tags
id - integer
name - string
taggables
tag_id - integer
taggable_id - integer
taggable_type - string
~~~
#### 模型結構
接下來,我們準備在模型上定義關系。在`Post`和`Video`車型都將有一個`tags`在定義的關系`$morphToMany`上基本模型類屬性:
~~~
class Post extends Model
{
public $morphToMany = [
'tags' => ['Acme\Blog\Models\Tag', 'name' => 'taggable']
];
}
~~~
#### 定義關系的逆關系
接下來,在`Tag`模型上,您應該為其每個相關模型定義一個關系。因此,對于此示例,我們將定義一個`posts`關系和一個`videos`關系:
~~~
class Tag extends Model
{
public $morphedByMany = [
'posts' => ['Acme\Blog\Models\Post', 'name' => 'taggable'],
'videos' => ['Acme\Blog\Models\Video', 'name' => 'taggable']
];
}
~~~
#### 檢索關系
定義數據庫表和模型后,您可以通過模型訪問關系。例如,要訪問帖子的所有標簽,您可以簡單地使用`tags`dynamic屬性:
~~~
$post = Post::find(1);
foreach ($post->tags as $tag) {
//
}
~~~
您還可以通過訪問`$morphedByMany`屬性中定義的關系的名稱,從多態模型中檢索多態關系的所有者。在我們的案例中,這就是模型上的`posts`或`videos`方法`Tag`。因此,您將這些關系作為動態屬性進行訪問:
~~~
$tag = Tag::find(1);
foreach ($tag->videos as $video) {
//
}
~~~
#### [](https://octobercms.com/docs/database/relations#custom-polymorphic-types)自定義多態類型
默認情況下,完全限定的類名用于存儲相關的模型類型。例如,給定上面的示例,其中a`Photo`可能屬于`Staff`或a`Product`,則默認`imageable_type`值分別為`Acme\Blog\Models\Staff`或`Acme\Blog\Models\Product`。
使用自定義多態類型可以使數據庫與應用程序的內部結構脫鉤。您可以定義一個關系“變形圖”以為每個模型提供一個自定義名稱,而不是類名稱:
~~~
use October\Rain\Database\Relations\Relation;
Relation::morphMap([
'staff' => 'Acme\Blog\Models\Staff',
'product' => 'Acme\Blog\Models\Product',
]);
~~~
`morphMap`在[插件注冊文件](https://octobercms.com/docs/plugin/registration#registration-methods)的`boot`方法中最常見的注冊位置。[](https://octobercms.com/docs/plugin/registration#registration-methods)
- 基本說明
- 基本操作
- October cms 安裝
- 后臺控制器路徑
- 圖標
- 獲取安裝網上的插件/主題
- 插件構造器使用
- 定時任務
- October后臺控制器
- vscode編輯器
- ajax操作
- 使用
- ajax更新組件
- ajax屬性API
- JavaScript API
- ajax綜合使用
- 主題
- 多語言主題
- 安裝市場主題
- 主題程序處理
- 主題
- 頁面
- 部件
- 布局
- 內容
- 組件
- 媒體
- 主題表單操作
- 表單使用
- 表單后端程序處理
- 插件
- 自定義插件
- 插件說明
- 插件導航條
- 插件數據庫設置
- 插件的設置管理
- 插件的配置文件config
- 組件
- app服務
- app容器
- 擴展行為
- 緩存
- Collection類
- Lazy Collections
- Collection方法
- 助手函數
- 數組助手函數
- 路徑助手函數
- 玄樂助手函數
- 其他助手函數
- 錯誤與記錄
- 事件處理
- HTML頁面
- 文件與目錄操作
- 散列和加密
- 郵件
- 郵件內容
- 郵件發送
- 分頁
- 模板解析器
- 動態解析器語法
- 隊列消息
- 請求與輸入
- 響應
- 視圖
- 路由器
- 配置
- 驗證操作
- 處理錯誤消息
- 錯誤消息與視圖
- 可用的驗證規則
- 有條件的驗證規則
- 驗證數組
- 錯誤消息
- 自定義驗證規則
- 模型操作
- 定義模型與其屬性
- 檢索模型
- 插入與更新
- 刪除模型
- 查詢范圍
- 事件操作
- 關聯操作
- 定義關系
- 關系類型
- 多肽關系
- 關系查詢
- 渴望加載
- 插入模型
- 數據庫操作
- 基本用法
- 數據表結構
- 查詢連貫操作
- 結果檢索
- select子句
- 插入更新
- where子句
- 排序,分組,限制和偏移
- 文件附件
- Collection操作
- 屬性操作
- 系列化json
- 數據庫屬性
- 數據庫行為
- 控制器
- 后臺控制器定義
- 后臺頁面
- 后臺組件
- 后臺表單
- 表單組件
- 表單視圖
- 表單行為
- 后臺列表
- 列表行為
- 列表過濾器
- 可用列類型
- 關系行為
- 關系行為類型
- 擴展關系行為
- 列表排序操作
- 導入導出操作
- 用于與權限
- corlate模板修改
- 修改頂部導航
- laravel問題
- 控制器不存在
- 控制器
- 路由組
- laravel筆記
- laravel 安裝
- 偽靜態配置
- 依賴注入 & 控制器
- 中間件
- 路由文件
- 視圖