laravel 多對多關聯,明確定義出關聯關係,自定義兩表與關聯表的關聯字段

laravel的官方文檔上面只介紹了belongsToMany的4個參數,文檔如下:




 到這裏爲止,官方文檔上面對於多對多關聯介紹差不多完了,如果想查看更多請看官方文檔

下面我來介紹在我們遇到兩個表進行多對多關聯,而且關聯的時候,設置這兩個表與中間表的關聯字段。

例如:

    a表結構爲:

        id 主鍵,

        tag 標識,

        …………

    b表結構爲:

        id 主鍵,

        …………

    a_b表結構爲:

        id 主鍵,

        b_id,

        a_tag

  當我們遇到這種情況的時候,查看官方文檔上並沒有找到相關的處理方法,官方文檔上面的介紹整體說下來 :

    belongsToMany(關聯表模型,中間表表名,中間表與當前模型的關聯字段,中間表與關聯表的關聯字段);

    如果我們上面的表結構按照這種方式關聯,假設我們當前模型爲a ;  那麼關聯寫爲 belongsToMany(b:class, 'a_b', 'a_tag', 'b_id');

 如果我們這麼寫的話,產生出來的sql爲:

    select * from b inner join a_b on b.id = a_b.id where a_b.a_tag = a.id;

這樣問題就出現了,我們實際上想要的sql語句爲:

    select * from b inner join a_b on b.id = a_b.id where a_b.a_tag = a.tag;

但是,我們應該怎麼做纔可以得到這樣的結果呢?

    那就需要看下關於belongsToMany()的第四、第五個參數了;

    我先貼上laravel源碼:

public function belongsToMany($related, $table = null, $foreignPivotKey = null, $relatedPivotKey = null,
                                  $parentKey = null, $relatedKey = null, $relation = null)
    {
        // If no relationship name was passed, we will pull backtraces to get the
        // name of the calling function. We will use that function name as the
        // title of this relation since that is a great convention to apply.
        if (is_null($relation)) {
            $relation = $this->guessBelongsToManyRelation();
        }

        // First, we'll need to determine the foreign key and "other key" for the
        // relationship. Once we have determined the keys we'll make the query
        // instances as well as the relationship instances we need for this.
        $instance = $this->newRelatedInstance($related);

        $foreignPivotKey = $foreignPivotKey ?: $this->getForeignKey();

        $relatedPivotKey = $relatedPivotKey ?: $instance->getForeignKey();

        // If no table name was provided, we can guess it by concatenating the two
        // models using underscores in alphabetical order. The two model names
        // are transformed to snake case from their default CamelCase also.
        if (is_null($table)) {
            $table = $this->joiningTable($related);
        }

        return $this->newBelongsToMany(
            $instance->newQuery(), $this, $table, $foreignPivotKey,
            $relatedPivotKey, $parentKey ?: $this->getKeyName(),
            $relatedKey ?: $instance->getKeyName(), $relation
        );
上面是源碼,我們主要看
return $this->newBelongsToMany(
            $instance->newQuery(), $this, $table, $foreignPivotKey,
            $relatedPivotKey, $parentKey ?: $this->getKeyName(),
            $relatedKey ?: $instance->getKeyName(), $relation
        );

我們看了上面的代碼後明確知道了,belongsToMany()有7個參數,我們通過官方文檔已經知道了前四個參數的作用,剩下兩個參數只能我們自己通過源碼來研究

$instance->newQuery(),$this, $table, $foreignPivotKey

返回值中的這幾個參數我就不多做描述了,我主要描述:

$relatedPivotKey, $parentKey ?: $this->getKeyName(),
            $relatedKey ?: $instance->getKeyName()

這兩個,也就是belongsToMany的第5、6個參數

第五個參數,我看了他的主要功能爲判斷是否傳入該參數如果沒有傳入這個參數就去調用getKeyName(); 有的人要問了getKeyName()是幹什麼的呢?我也想問,然後我就繼續查看了geiKeyName()的源碼。這個方法是Model類的一個方法,用來獲取表主鍵的.這僅僅說了getKeyName()方法,不是還有個$this沒有說它到底指向的誰?它指向的是當前調用belongsToMany()的模型。

第六個參數與第五個參數作用是一樣的,只是獲取的模型不同而已。這個參數獲取的是關聯表的主鍵.


參數講完了,我們傳入後會得到什麼樣的sql呢?

belongsToMany(b:class,  'a_b',  'a_tag',  'b_id', 'tag', 'id');

下面我們就來看看到底會得到怎樣的sql:

    select * from b inner join a_b on b.id = a_b.id where a_b.a_tag = a.tag ; 這就是我們得到的sql;

仔細看看,是不是和我們上面想要得到的sql語句一樣?


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章