佳木斯湛栽影视文化发展公司

主頁(yè) > 知識(shí)庫(kù) > 詳解Laravel設(shè)置多態(tài)關(guān)系模型別名的方式

詳解Laravel設(shè)置多態(tài)關(guān)系模型別名的方式

熱門(mén)標(biāo)簽:阿里云 Linux服務(wù)器 服務(wù)器配置 銀行業(yè)務(wù) 科大訊飛語(yǔ)音識(shí)別系統(tǒng) 電子圍欄 團(tuán)購(gòu)網(wǎng)站 Mysql連接數(shù)設(shè)置

作為 Laravel 的重度使用者肯定都對(duì)多態(tài)關(guān)系不默生,以官方文檔為例,文章有標(biāo)簽,視頻有標(biāo)簽,那么文章和視頻這些模型與標(biāo)簽?zāi)P偷年P(guān)系就是 多態(tài)多對(duì)多(Many To Many (Polymorphic))

如果我們給 ID 為 1 的文章打上兩個(gè)標(biāo)簽,數(shù)據(jù)庫(kù)標(biāo)簽關(guān)系表的的存儲(chǔ)結(jié)果就是這樣子:

> select * from taggables;
+--------+-------------+---------------+
| tag_id | taggable_id | taggable_type |
+--------+-------------+---------------+
|  1 |   1 | App\Post  |
|  2 |   1 | App\Post  |
+--------+-------------+---------------+

相信有不少人和我一樣希望 taggable_type 的值不要直接用模型類(lèi)名,而是使用表名: 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

我們可以將這個(gè)定義寫(xiě)到 AppServiceProvider 中,但是有一個(gè)非常嚴(yán)重的問(wèn)題: 我們?cè)谛略龌蛘邉h除模型的時(shí)候,會(huì)很容易忘記去更新這個(gè)定義 。我已經(jīng)至少出現(xiàn)這個(gè)問(wèn)題 3 次了,所以我一直在糾結(jié)有沒(méi)有更好的方法,今天突然靈機(jī)一動(dòng),實(shí)現(xiàn)了一個(gè)看起來(lái)似乎是一個(gè)不錯(cuò)的方式,分享給大家。

思路來(lái)源

我嘗試跟蹤了一遍源碼,發(fā)現(xiàn)模型中有一個(gè)方法 getMorphClass ,多態(tài)關(guān)聯(lián)的時(shí)候,就是用它來(lái)取目標(biāo)對(duì)象的類(lèi)型名稱(chēng)的,默認(rèn)返回類(lèi)名:

public function getMorphClass()
{
 $morphMap = Relation::morphMap();
 if (! empty($morphMap)  in_array(static::class, $morphMap)) {
  return array_search(static::class, $morphMap, true);
 }
 return static::class;
}

那么,只要我們?cè)谀P椭懈采w這個(gè)方法便可以方便的實(shí)現(xiàn)目標(biāo)了。

實(shí)現(xiàn)目標(biāo)

我們有兩個(gè)選擇去實(shí)現(xiàn)它:

  1. 創(chuàng)建一個(gè)模型基類(lèi)覆蓋這個(gè)方法,所有的模型都來(lái)集成它即可;
  2. 創(chuàng)建一個(gè) trait,在需要的模型中引入它。

我當(dāng)然會(huì)選擇 trait 方式來(lái)實(shí)現(xiàn),不管從定義還是代碼耦合度上,使用 trait 來(lái)解決這類(lèi)特性需求都是再適合不過(guò)了,如果你對(duì) trait 還不太熟悉,可以閱讀我之前的文章: 《我所理解的 PHP Trait》

我們的目標(biāo)是使用表名來(lái)做為關(guān)系類(lèi)別名,那么在模型中如何獲取表名呢,直接使用模型的 getTable 即可,那么整個(gè) trait 的實(shí)現(xiàn)如下:

app/Traits/UseTableNameAsMorphClass.php
?php
namespace App\Traits;
trait UseTableNameAsMorphClass
{
 public function getMorphClass()
 {
  return $this->getTable();
 }
}

然后在我們需要用到關(guān)系類(lèi)型的模型中引入它即可:

?php
namespace App;
use App\Traits\UseTableNameAsMorphClass;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
 use UseTableNameAsMorphClass;

 //...
}

友情提示

當(dāng)然,如果你習(xí)慣給表名加前綴,或者你的表名與模型名不太一致,那么,你只需要修改 trait 中 getMorphClass 的實(shí)現(xiàn)即可,我個(gè)人的習(xí)慣是模型名就是表名的單數(shù),不帶前綴。

總結(jié)

以上所述是小編給大家介紹的Laravel設(shè)置多態(tài)關(guān)系模型別名的方式,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!如果你覺(jué)得本文對(duì)你有幫助,歡迎轉(zhuǎn)載,煩請(qǐng)注明出處,謝謝!

您可能感興趣的文章:
  • Laravel5.1 框架模型查詢(xún)作用域定義與用法實(shí)例分析
  • Laravel5.1 框架模型工廠ModelFactory用法實(shí)例分析
  • Laravel5.1 框架模型軟刪除操作實(shí)例分析
  • Laravel5.1 框架模型創(chuàng)建與使用方法實(shí)例分析
  • Laravel 5框架學(xué)習(xí)之模型、控制器、視圖基礎(chǔ)流程
  • Laravel模型間關(guān)系設(shè)置分表的方法示例
  • Laravel關(guān)系模型指定條件查詢(xún)方法
  • Laravel 實(shí)現(xiàn)關(guān)系模型取出需要的字段
  • Laravel模型事件的實(shí)現(xiàn)原理詳解
  • Laravel框架模型的創(chuàng)建及模型對(duì)數(shù)據(jù)操作示例
  • Laravel使用模型實(shí)現(xiàn)like模糊查詢(xún)的例子
  • Laravel5.1 框架模型一對(duì)一關(guān)系實(shí)現(xiàn)與使用方法實(shí)例分析

標(biāo)簽:廣元 衡水 蚌埠 萍鄉(xiāng) 江蘇 大理 衢州 棗莊

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《詳解Laravel設(shè)置多態(tài)關(guān)系模型別名的方式》,本文關(guān)鍵詞  ;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問(wèn)題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無(wú)關(guān)。
  • 相關(guān)文章
  • 收縮
    • 微信客服
    • 微信二維碼
    • 電話咨詢(xún)

    • 400-1100-266
    措美县| 游戏| 汨罗市| 施甸县| 普宁市| 扎赉特旗| 嘉峪关市| 东源县| 赞皇县| 微山县| 韩城市| 北票市| 荆州市| 华亭县| 大石桥市| 射阳县| 平武县| 镇雄县| 曲麻莱县| 平定县| 崇礼县| 永宁县| 卓资县| 张北县| 定西市| 宽甸| 镇原县| 惠来县| 庄河市| 衡水市| 苏尼特左旗| 茌平县| 广平县| 河池市| 抚松县| 府谷县| 阜南县| 赣州市| 桂林市| 浦北县| 莱阳市|