iT邦幫忙

2021 iThome 鐵人賽

DAY 14
0
Modern Web

工作後才知道的後端 30 件小事系列 第 18

如何讓 Laravel Eloquent 支援 composite key

Composite key

一般表 (table) 是只有一個主鍵 (primary key),而複合主鍵 (composite key) 是指多個欄位作為主鍵。

而 Laravel Eloquent 是不支援 composite key 的。

方法ㄧ:Overwrite extended methods

在要使用 composite key 的 model 加入以下的 code 去覆寫繼承的方法。

/**
 * Set the keys for a save update query.
 *
 * @param  \Illuminate\Database\Eloquent\Builder  $query
 * @return \Illuminate\Database\Eloquent\Builder
 */
protected function setKeysForSaveQuery(Builder $query)
{
    $keys = $this->getKeyName();
    if (!is_array($keys)) {
        return parent::setKeysForSaveQuery($query);
    }

    foreach ($keys as $keyName) {
        $query->where($keyName, '=', $this->getKeyForSaveQuery($keyName));
    }

    return $query;
}

/**
 * Get the primary key value for a save query.
 *
 * @param mixed $keyName
 * @return mixed
 */
protected function getKeyForSaveQuery($keyName = null)
{
    //dd($keyName);
    if (is_null($keyName)) {
        $keyName = $this->getKeyName();
    }

    if (isset($this->original[$keyName])) {
        return $this->original[$keyName];
    }

    return $this->getAttribute($keyName);
}

方法二:Use Trait

Make the codes of solution 2 as a trait, then use the trait at models that need

本質上跟方法 1 一樣,只是把修改的部分包裝成一個 trait,方便在多個 model 引用,也比較好維護。

方法三:Use Package

使用套件:

方法四: Don't use composite key

或許最好的方法就是不要用 XD

雖然找了幾種解法,但最後開發時還是遇到問題。如果不使用套件的話,很多要用到 getKey() 的方法就會壞掉,像是 save() 我記得就有用到,所以我的 composite key model 在要 save 時就會噴錯;而 Compoships 我後來沒實際使用,但它在文件也說明該套件在 relationship 部分功能有其局限性。

所以最後跟同事討論後,還是做成單一主鍵了,比較省事。


上一篇
Postman pre-request script & tests
下一篇
面試題:什麼是 SQL injection?如何預防?
系列文
工作後才知道的後端 30 件小事19

尚未有邦友留言

立即登入留言