詳解Laravel設置多態(tài)關系模型別名的方式
作為 Laravel 的重度使用者肯定都對多態(tài)關系不默生,以官方文檔為例,文章有標簽,視頻有標簽,那么文章和視頻這些模型與標簽模型的關系就是 多態(tài)多對多(Many To Many (Polymorphic))
如果我們給 ID 為 1 的文章打上兩個標簽,數(shù)據(jù)庫標簽關系表的的存儲結果就是這樣子:
> select * from taggables; +--------+-------------+---------------+ | tag_id | taggable_id | taggable_type | +--------+-------------+---------------+ | 1 | 1 | App\Post | | 2 | 1 | App\Post | +--------+-------------+---------------+
相信有不少人和我一樣希望 taggable_type 的值不要直接用模型類名,而是使用表名: posts 。官方文檔的建議是:
use Illuminate\Database\Eloquent\Relations\Relation; Relation::morphMap([ 'posts' => 'App\Post', 'videos' => 'App\Video', ]);
https://laravel.com/docs/6.x/eloquent-relationships#custom-polymorphic-types
我們可以將這個定義寫到 AppServiceProvider 中,但是有一個非常嚴重的問題: 我們在新增或者刪除模型的時候,會很容易忘記去更新這個定義 。我已經(jīng)至少出現(xiàn)這個問題 3 次了,所以我一直在糾結有沒有更好的方法,今天突然靈機一動,實現(xiàn)了一個看起來似乎是一個不錯的方式,分享給大家。
思路來源
我嘗試跟蹤了一遍源碼,發(fā)現(xiàn)模型中有一個方法 getMorphClass ,多態(tài)關聯(lián)的時候,就是用它來取目標對象的類型名稱的,默認返回類名:
public function getMorphClass()
{
$morphMap = Relation::morphMap();
if (! empty($morphMap) && in_array(static::class, $morphMap)) {
return array_search(static::class, $morphMap, true);
}
return static::class;
}
那么,只要我們在模型中覆蓋這個方法便可以方便的實現(xiàn)目標了。
實現(xiàn)目標
我們有兩個選擇去實現(xiàn)它:
- 創(chuàng)建一個模型基類覆蓋這個方法,所有的模型都來集成它即可;
- 創(chuàng)建一個 trait,在需要的模型中引入它。
我當然會選擇 trait 方式來實現(xiàn),不管從定義還是代碼耦合度上,使用 trait 來解決這類特性需求都是再適合不過了,如果你對 trait 還不太熟悉,可以閱讀我之前的文章: 《我所理解的 PHP Trait》
我們的目標是使用表名來做為關系類別名,那么在模型中如何獲取表名呢,直接使用模型的 getTable 即可,那么整個 trait 的實現(xiàn)如下:
app/Traits/UseTableNameAsMorphClass.php
<?php
namespace App\Traits;
trait UseTableNameAsMorphClass
{
public function getMorphClass()
{
return $this->getTable();
}
}
然后在我們需要用到關系類型的模型中引入它即可:
<?php
namespace App;
use App\Traits\UseTableNameAsMorphClass;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
use UseTableNameAsMorphClass;
//...
}
友情提示
當然,如果你習慣給表名加前綴,或者你的表名與模型名不太一致,那么,你只需要修改 trait 中 getMorphClass 的實現(xiàn)即可,我個人的習慣是模型名就是表名的單數(shù),不帶前綴。
總結
以上所述是小編給大家介紹的Laravel設置多態(tài)關系模型別名的方式,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!如果你覺得本文對你有幫助,歡迎轉載,煩請注明出處,謝謝!
- Laravel5.1 框架模型查詢作用域定義與用法實例分析
- Laravel5.1 框架模型工廠ModelFactory用法實例分析
- Laravel5.1 框架模型軟刪除操作實例分析
- Laravel5.1 框架模型創(chuàng)建與使用方法實例分析
- Laravel 5框架學習之模型、控制器、視圖基礎流程
- Laravel模型間關系設置分表的方法示例
- Laravel關系模型指定條件查詢方法
- Laravel 實現(xiàn)關系模型取出需要的字段
- Laravel模型事件的實現(xiàn)原理詳解
- Laravel框架模型的創(chuàng)建及模型對數(shù)據(jù)操作示例
- Laravel使用模型實現(xiàn)like模糊查詢的例子
- Laravel5.1 框架模型一對一關系實現(xiàn)與使用方法實例分析
相關文章
自定義min版smarty模板引擎MinSmarty.class.php文件及用法
這篇文章主要介紹了自定義min版smarty模板引擎MinSmarty.class.php文件及用法,可實現(xiàn)簡單的Smarty模板變量替換與輸出顯示等功能,具有一定參考借鑒價值,需要的朋友可以參考下2016-05-05
PHP設計模式(五)適配器模式Adapter實例詳解【結構型】
這篇文章主要介紹了PHP設計模式:適配器模式Adapter,結合實例形式詳細分析了PHP適配器模式Adapter基本概念、功能、原理、用法及操作注意事項,需要的朋友可以參考下2020-05-05
php實現(xiàn)爬取和分析知乎用戶數(shù)據(jù)
本文給大家介紹的是利用php的curl編寫的爬取知乎用戶數(shù)據(jù)的爬蟲,并分析用戶的各種屬性,有需要的小伙伴可以參考下2016-01-01
PHP使用SOAP調用.net的WebService數(shù)據(jù)
需要和一個.net系統(tǒng)進行數(shù)據(jù)交換,對方提供了一個WebService接口,使用PHP如何調用這個數(shù)據(jù)呢,下面就看看使用SOAP調用的方法吧2013-11-11
Laravel 5.4中migrate報錯: Specified key was too long error的解決
今天在執(zhí)行l(wèi)aravel migrate時出現(xiàn)異常,找了好半天才找到問題所在,所以這篇文章主要給大家介紹了關于Laravel 5.4中migrate報錯: Specified key was too long error的解決方法,需要的朋友可以參考下。2017-11-11
如何使用php腳本給html中引用的js和css路徑打上版本號
這篇文章主要介紹了如何使用php腳本給html中引用的js和css路徑打上版本號,打版本號有個好處就是可以解決外部應用文件實時更新問題,喜歡的朋友一起看看全文吧2015-11-11

