您好,登錄后才能下訂單哦!
怎么在Laravel中設置多態關系模型別名?很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。
> 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 中,但是有一個非常嚴重的問題: 我們在新增或者刪除模型的時候,會很容易忘記去更新這個定義 。我已經至少出現這個問題 3 次了,所以我一直在糾結有沒有更好的方法,今天突然靈機一動,實現了一個看起來似乎是一個不錯的方式,分享給大家。
思路來源
我嘗試跟蹤了一遍源碼,發現模型中有一個方法 getMorphClass ,多態關聯的時候,就是用它來取目標對象的類型名稱的,默認返回類名:
public function getMorphClass() { $morphMap = Relation::morphMap(); if (! empty($morphMap) && in_array(static::class, $morphMap)) { return array_search(static::class, $morphMap, true); } return static::class; }
那么,只要我們在模型中覆蓋這個方法便可以方便的實現目標了。
實現目標
我們有兩個選擇去實現它:
創建一個模型基類覆蓋這個方法,所有的模型都來集成它即可;
創建一個 trait,在需要的模型中引入它。
我當然會選擇 trait 方式來實現,不管從定義還是代碼耦合度上,使用 trait 來解決這類特性需求都是再適合不過了,如果你對 trait 還不太熟悉,可以閱讀我之前的文章: 《我所理解的 PHP Trait》
我們的目標是使用表名來做為關系類別名,那么在模型中如何獲取表名呢,直接使用模型的 getTable 即可,那么整個 trait 的實現如下:
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; //... }
Laravel 是一套簡潔、優雅的PHP Web開發框架。它可以讓你從面條一樣雜亂的代碼中解脫出來;它可以幫你構建一個完美的網絡APP,而且每行代碼都可以簡潔、富于表達力。
看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。