Laravel с 2 первичными ключами - обновить метод «приращения»? - PullRequest
1 голос
/ 29 октября 2019

Я использую это решение для 2 первичных ключей в Laravel: https://stackoverflow.com/a/37076437/225114

Может кто-нибудь сказать мне, как также переопределить метод «увеличения» Eloquent для работы с дублирующимися ключами?

Laravel Framework 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);
  }

}

Спасибо.

1 Ответ

0 голосов
/ 30 октября 2019

Самое первое, что вам нужно сделать, это посмотреть на структуру таблицы и проверить ваши первичные ключи. Они должны быть объявлены как первичные и не могут увеличиваться.

Если вы используете миграцию Laravel для своей модели, она должна выглядеть следующим образом:

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

        ...

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

Если это чисто, просто добавьте следующееФункция в начале вашей черты:

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

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

И установите вашу черту в начале вашей модели, а не в конце. Вот и все.

...
class Devices extends Model
{

    use CompositePrimaryKey;

    ...

Наконец, вы можете удалить объявление переменной в вашей модели public $incrementing = false;, потому что теперь это избыточно.

...