首页 > 解决方案 > 带有 2 个主键的 Laravel - 更新“增量”方法?

问题描述

我将此解决方案用于 Laravel 中的 2 个主键: https ://stackoverflow.com/a/37076437/225114

谁能告诉我如何覆盖 Eloquent “增量” 方法以使用重复键?

Laravel 框架 5.8.35

我将“CompositePrimaryKey”特征包含在模型中,例如...

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use App\Models\Traits\CompositePrimaryKey;

class Devices extends Model
{
    public $table = 'devices';
    protected $primaryKey = ['id1','id2'];
    public $incrementing = false;
    public $timestamps = false;

    use CompositePrimaryKey;

}

这是特征:

namespace App\Models\Traits;

use Illuminate\Database\Eloquent\Builder;

trait CompositePrimaryKey {
    /**
     * 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)
    {
        if(is_null($keyName)){
            $keyName = $this->getKeyName();
        }

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

        return $this->getAttribute($keyName);
    }
    /**
   * Perform the actual delete query on this model instance.
   *
   * @return void
   */
  protected function runSoftDelete()
  {
    $query = $this->newQueryWithoutScopes()->where($this->getKeyName()[0], $this->attributes[$this->getKeyName()[0]])
    ->where($this->getKeyName()[1], $this->attributes[$this->getKeyName()[1]]);
    $time = $this->freshTimestamp();
    $columns = [$this->getDeletedAtColumn() => $this->fromDateTime($time)];
    $this->{$this->getDeletedAtColumn()} = $time;
    if ($this->timestamps && ! is_null($this->getUpdatedAtColumn())) {
      $this->{$this->getUpdatedAtColumn()} = $time;

      $columns[$this->getUpdatedAtColumn()] = $this->fromDateTime($time);
    }
    $query->update($columns);
  }

}

谢谢。

标签: laraveleloquentcomposite-primary-key

解决方案


您需要做的第一件事是查看您的表结构并检查您的主键。这些必须被声明为主要的并且不能增加。

如果您为模型使用 laravel 迁移,它应该如下所示:

public function up()
{
    Schema::create('devices', function (Blueprint $table) {
        $table->bigInteger('id1');
        $table->string('id2');

        ...

        $table->primary(['id1', 'id2']);
    });
}

如果这个是干净的,只需在你的 trait 开头添加以下函数:

...
use Illuminate\Database\Eloquent\Builder;

trait CompositePrimaryKey
{
    public function getIncrementing()
    {
        return false;
    }

并将您的特征设置在模型的开头,而不是结尾。而已。

...
class Devices extends Model
{

    use CompositePrimaryKey;

    ...

最后,您可以删除模型中变量的声明public $incrementing = false;,因为它现在是多余的。


推荐阅读