如何让 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?如何预防?

DAY24 - 利用 uptime 让你的 Heroku 永不休眠

上一篇成功将 Nestjs 部属到 heroku 上面,不过我们使用的是免费方案,免费方案有几个限制...

2020it邦铁人赛-30天手把手的Vue.js教学 Day30 - 关心时事! 做个简单的COVID-19追踪app吧!(下)

tags: Vue.js ItIron2020 前言 昨天我们已经成功了做出了六个图表,利用将整理成...

[Day 15] 实作 OpenAPI Plugin 产生 API 文件

为什麽我想自己实作 Ktor OpenAPI Generator? 大多数的 Web 框架都有官方或...

[Day 19] 第一主餐 pt.11-财报资料,我全都要

上一篇我们修改了资料库 并且成功地把BeautifulSoup的资料送到Database内了 今天我...

使用 DOM Parser 取值

这篇会讲解怎麽样用 DOM 的 parser 把 RSS 资讯拿出来,首先我们可以先 new 一个 ...