【问题标题】:How to create composite key in ORM Eloquent Laravel 6.2如何在 ORM Eloquent Laravel 6.2 中创建复合键
【发布时间】:2020-02-10 07:31:32
【问题描述】:

我想在我的数据库中的两个表之间创建一个复合键。我已经找到了如何在迁移中创建它,但是对于 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']);
});

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

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

【问题讨论】:

  • 我不明白你在做什么。你的代码看起来不错。请举一个具体的例子来说明你想要达到的目标。
  • 不幸的是,Eloquent 不能拥有复合主键。您是否有理由需要它作为复合主键,而不是仅仅为字段添加唯一索引?
  • 在我的应用程序中使用复合键的示例,或者代码示例?
  • 是的,我需要它,因为对于一份合同,我不希望在同一年的同一个月有两次通过
  • 我不知道,因为我需要检查月份和年份是否已经被该合同的另一个段落占用。编辑:也许我可以在模型中检查,但我不确定在哪里

标签: php laravel eloquent laravel-6.2


【解决方案1】:

根据 laravel,Eloquent 不支持复合主键。 你可以在 laravel github 仓库here查看这个问题

如果您真的想这样做,那么您可以覆盖 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) 时调用,它的作用是在 SQL 中生成 WHERE 子句。

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

   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;

【讨论】:

  • 谢谢它只是工作。不知道为什么在 laravel 中没有实现,用起来就是这么简单。
  • @MrSolarius 如果你有一个复合键,那么每个引用该表的关系都需要复制复合键的所有列,这通常并不理想。
猜你喜欢
  • 1970-01-01
  • 2016-07-01
  • 1970-01-01
  • 2020-03-14
  • 1970-01-01
  • 2015-05-08
  • 1970-01-01
  • 2015-12-06
  • 2013-07-07
相关资源
最近更新 更多