Laravel Model 利用 Macroable 爲數據模型添加宏能力

什麼是ThinkSNS ?

ThinkSNS(簡稱TS),一款全平臺綜合性社交系統,爲國內外大中小企業和創業者提供社會化軟件研發及技術解決方案,目前最新版本爲ThinkSNS+(簡稱TS+)、ThinkSNS V四、ThinkSNS【簡】。php

 

產生需求

 

在使用 Laravel 開發 ThinkSNS Plus 的時候,由於不少功能塊都沒有寫在一個庫裏面,利用拓展包的形式添加實際功能,裏面不少地方也用到了「多態多對多」的關係。問題來了,開發一個問答程序,想要給用戶模型增長髮布的問題或者回答的關係,起初是繼承一份 User 模型,添加了關係,以後就發現問題了,由於用戶的 tag 是使用多態多對多的關係,我經過繼承的用戶模型是沒法拿到這種關係數據的由於 ***able_type 是 user 數據模型類名稱或者別名。而我繼承以後類也就發生改變了。html

完成需求

隨之想到,在 Laravel 中有一個 Trait 叫作 Macroable 而後發現 Builder 都有這種能力,而 Model 沒有,隨之也將這個 Trait 添加到要使用的model上,後來發現,若是其餘模型也要用是否是也要再添加一次?隨之寫了一份 Trait :git

trait Macroable
{
    use \Illuminate\Support\Traits\Macroable {
        __call as macroCall;
    }

    /**
     * Get a relationship value from a method.
     *
     * @param string $key
     * @return mixed
     * @author Seven Du <shiweidu@outlook.com>
     */
    public function getRelationValue($key)
    {
        $relation = parent::getRelationValue($key);
        if (! $relation && static::hasMacro($key)) {
            return $this->getRelationshipFromMethod($key);
        }

        return $relation;
    }

    /**
     * Handle dynamic method calls into the model.
     *
     * @param string $method
     * @param array $parameters
     * @return mixed
     * @author Seven Du <shiweidu@outlook.com>
     */
    public function __call($method, $parameters)
    {
        if (static::hasMacro($method)) {
            return $this->macroCall($method, $parameters);
        }

        return parent::__call($method, $parameters);
    }

    /**
     * Handle dynamic static method calls into the method.
     *
     * @param  string  $method
     * @param  array  $parameters
     * @return mixed
     */
    public static function __callStatic($method, $parameters)
    {
        return parent::__callStatic($method, $parameters);
    }
}

只要在要使用的 model 中 use 便可。github

使用

有了這個 Trait 那麼咱們添加到 User 模型中,就能夠使用宏能力爲其動態添加函數了:函數

User::macro('questions', function () {
    return $this->hasMany(Question::class, 'user_id', 'id');
});

這樣,咱們能夠直接 :
ui

$questions = $user->questions;

拿到用戶發佈的全部問題了。
this

以上代碼都來自於ThinkSNS Plus,看完整的開發代碼能夠看倉庫spa

GitHub: https://github.com/slimkit/thinksns-plus(開源不易,求 Star )code

 

上一篇研發日記:如何在 Laravel 中 「規範」 的開發驗證碼發送功能htm

相關文章
相關標籤/搜索