risentveber
@risentveber
fullstack web developer

Как Model.firstOrNew(attr) может приводить к duplicate key value violates unique constraint по полям attr?

Данный код
private function mobKills($count, $mob_id, $player_id)
    {
        $mobKill = PlayerMobKill::firstOrNew([
            'player_id' => $player_id,
            'mob_id' => $mob_id
        ]);

        $mobKill->incrementOrSave('count', $count);
    }

приводит к следующей ошибке:
Next Illuminate\Database\QueryException: SQLSTATE[23505]: Unique violation: 7 ERROR:  duplicate key value violates unique constraint "player_mob_kills_player_id_mob_id_unique"
DETAIL:  Key (player_id, mob_id)=(53768, 673) already exists. (SQL: insert into "player_mob_kills" ("player_id", "mob_id", "count") values (53768, 673, 1) returning "id") in /var/www/cw-game/releases/720/vendor/laravel/framework/src/Illuminate/Database/Connection.php:651
Stack trace:
#0 /var/www/cw-game/releases/720/vendor/laravel/framework/src/Illuminate/Database/Connection.php(611): Illuminate\Database\Connection->runQueryCallback('insert into "pl...', Array, Object(Closure))
#1 /var/www/cw-game/releases/720/vendor/laravel/framework/src/Illuminate/Database/Connection.php(324): Illuminate\Database\Connection->run('insert into "pl...', Array, Object(Closure))
#2 /var/www/cw-game/releases/720/vendor/laravel/framework/src/Illuminate/Database/Connection.php(298): Illuminate\Database\Connection->select('insert into "pl...', Array, false)
#3 /var/www/cw-game/releases/720/vendor/laravel/framework/src/Illuminate/Database/Query/Processors/PostgresProcessor.php(20): Illuminate\Database\Connection->selectFromWriteConnection('insert into "pl...', Array)
#4 /var/www/cw-game/releases/720/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php(1821): Illuminate\Database\Query\Processors\PostgresProcessor->processInsertGetId(Object(Illuminate\Database\Query\Builder), 'insert into "pl...', Array, 'id')
#5 [internal function]: Illuminate\Database\Query\Builder->insertGetId(Array, 'id')
#6 /var/www/cw-game/releases/720/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php(949): call_user_func_array(Array, Array)
#7 /var/www/cw-game/releases/720/bootstrap/cache/compiled.php(10494): Illuminate\Database\Eloquent\Builder->__call('insertGetId', Array)
#8 /var/www/cw-game/releases/720/bootstrap/cache/compiled.php(10483): Illuminate\Database\Eloquent\Model->insertAndSetId(Object(Illuminate\Database\Eloquent\Builder), Array)
#9 /var/www/cw-game/releases/720/bootstrap/cache/compiled.php(10434): Illuminate\Database\Eloquent\Model->performInsert(Object(Illuminate\Database\Eloquent\Builder), Array)
#10 /var/www/cw-game/releases/720/app/Models/Model.php(26): Illuminate\Database\Eloquent\Model->save()
#11 /var/www/cw-game/releases/720/app/Services/Persist.php(208): App\Models\Model->incrementOrSave('count', '1')
#12 /var/www/cw-game/releases/720/app/Services/Persist.php(130): App\Services\Persist->mobKills('1', 673, 53768)

Как и почему такое происходит?
  • Вопрос задан
  • 644 просмотра
Пригласить эксперта
Ответы на вопрос 2
Sanasol
@Sanasol Куратор тега Laravel
нельзя просто так взять и загуглить ошибку
Покажите таблицу, модель и т.д.

Что такое incrementOrSave, в последней версии Eloquent/Laravel такой функции нет.
Ответ написан
miraage
@miraage
Старый прогер
Конкретно данный пример.

Ищет или создает запись по заданному предикату.
Если запись существует, вызывается стандартный метод increment модели Eloquent.
Если запись не существует, выставляется аттрибут с указанным значением и происходит сохранение.

Ввиду того, что этот метод писал я, и все работало, могу сказать одно: проблема во входящих данных.

P.S. удачки там на кликере)
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы