Почему переписываются предыдущие поля при генерации поля через boot?

<?php namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Test extends Model
{
    protected $table = "test";
    protected $fillable = ['id', 'barcode'];

    public static function boot()
    {
        parent::boot();
        self::creating(function ($model) {
            $increment = \DB::table($model->table)->increment('barcode') + 1;
            $increment = str_pad($increment, 10, '0', STR_PAD_LEFT);
            $model->barcode = (string)"ST" . $increment;
        });
    }
}


Вот пример модели, при создании новой модели Test::create(), создается новый с нормальным баркодом, но у предыдущего становиться в 1, при повторной попытке первый становить 2, второй в 1, а 3 в нормальном нужном формате. Поле баркода строка.
1,2,2018-07-10 11:07:19,2018-07-10 11:07:19
2,1,2018-07-10 11:07:23,2018-07-10 11:07:23
3,ST0000000003,2018-07-10 11:07:28,2018-07-10 11:07:28


вот миграция
<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateTestTable extends Migration
{
    public function up()
    {
        Schema::create('test', function (Blueprint $table) {
            $table->increments('id');
            $table->string('barcode');
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::dropIfExists('test');
    }
}
  • Вопрос задан
  • 59 просмотров
Пригласить эксперта
Ответы на вопрос 1
@Yan-s
https://laravel.ru/docs/v5/queries#increment

$increment = \DB::table($model->table)->increment('barcode') + 1;

метод increment() увеличивает значение поля на 1, раз у вас нет условий в запросе то запрос затрагивает все записи в таблице.

Кстати, прикольно что у вас вообще что то работает, ибо инкриминируете вы строку. Barcode у вас же строка начинающаяся с "ST" как это вы намереваетесь к ней единицу добавлять простым сложением?

Вот чего вам стоит сделать:
1. Используйте в качестве счетчика либо id записи, либо создайте отдельное поле в БД и храните там обычное целочисленное.
2. Добавляйте префикс "ST" (и пэд из нулей и всё что вам надо) к этому полю мутатором ( https://laravel.ru/docs/v5/eloquent-mutators#%D0%B... ) если у вас префикс фиксированный, то нечего его в БД писать. А если не фиксированный, то пишите в отдельное поле.
3. Нафига вам self::creating в boot() ? Создайте отдельный метод для добавления записи и вынесите всю логику добавления этой записи в него. Будете вызывать метод напрямую и передавать в него данные и не надо держать в уме что где то там потом чото еще по событию происходит.
4. Далее если вы используете отдельное поле для счетчика (а если будете использовать id, то он и так автоинкрементный). Перед сохранением получаете максимальное значение счетчика из бд ( https://laravel.ru/docs/v5/queries#%D0%B0%D0%B3%D1... ) добавляете еденицу.
5. Заворачиваете всё это дело в транзакцию https://laravel.ru/docs/v5/database#%D1%82%D1%80%D...

\DB::table($model->table) зачем? Выж унаследовались от ORM модели, работайте как с ORM моделью. Вот же https://laravel.ru/docs/v5/eloquent#%D0%BF%D0%BE%D...
Ответ написан
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы