首页 > 解决方案 > 如何在 ORM Eloquent Laravel 6.2 中创建复合键

问题描述

我想在我的数据库中的两个表之间创建一个复合键。我已经找到了如何在迁移中创建它,但是对于 Eloquente ORM,我什么也没找到。

所以这是我的迁移:

Schema::create('passages', function (Blueprint $table) {
            $table->unsignedBigInteger('id_contract');
            $table->integer('month');
            $table->integer('year');
            $table->text('object');
            $table->integer('nbPassage');
            $table->decimal('priceExclTax');
            $table->timestamps();

            $table->foreign('id_contract')->references('id')->on('contracts');
            $table->primary(['id_contract','mois','annee']);
});

所以我试图在模型中建立一个归属关系,但是当我尝试保存我的对象时没有附加任何内容,并且我的数据库中没有任何行。所以我认为这是错误的方式。

如果你有想法,请帮助我^^。

标签: phplaraveleloquentlaravel-6.2

解决方案


根据 laravel,Eloquent 不支持复合主键。您可以在此处的 laravel github 存储库上查看此问题

如果您真的想这样做,那么您可以覆盖setKeysForSaveQueryModel.php设置您的密钥。

默认情况下:

protected function setKeysForSaveQuery(Builder $query)
{
    $query->where($this->getKeyName(), '=', $this->getKeyForSaveQuery());

    return $query;
}

$this->getKeyName()将返回主键名称 $this->getKeyForSaveQuery()并将返回键的值。

这意味着 Eloquent 总是只过滤 1 个字段。

这将在您执行save操作 ( UPDATE and DELETE) 时调用,它的作用是WHERE在 SQL 中生成一个子句。

例如,将其放入使用复合主键的模型中:

   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;
    }

    
    protected function getKeyForSaveQuery($keyName = null)
    {
        if(is_null($keyName)){
            $keyName = $this->getKeyName();
        }

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

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

如果您在 setKeysForSaveQuery() 定义中使用 Builder 参数类型,那么您还需要将以下内容添加到模型的顶部:

use Illuminate\Database\Eloquent\Builder;

推荐阅读