V
V
Vladimir Singhtlov2018-07-10 14:31:21
Laravel
Vladimir Singhtlov, 2018-07-10 14:31:21

Why are the previous fields overwritten when the field is generated via 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;
        });
    }
}

Here is an example of a model, when creating a new model Test::create(), a new one is created with a normal barcode, but the previous one becomes 1, when you try again, the first becomes 2, the second becomes 1, and 3 in the normal desired format. Barcode field string.
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

here is the migration
<?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');
    }
}

Answer the question

In order to leave comments, you need to log in

1 answer(s)
Y
Yan-s, 2018-07-10
@Yan-s

https://laravel.ru/docs/v5/queries#increment
the increment() method increases the value of the field by 1, since you have no conditions in the query, then the query affects all records in the table.
By the way, it's cool that something works for you at all, because you are incriminating a line. Barcode you have a string starting with "ST" how do you intend to add one to it by simple addition?
Here's what you should do:
1. Use either the id of the record as a counter, or create a separate field in the database and store a regular integer there.
2. Add "ST" prefix (and a pad of zeros and everything you need) to this field with a mutator ( https://laravel.ru/docs/v5/eloquent-mutators#%D0%B... ) if you have the prefix is ​​fixed, then there is nothing to write it to the database. And if not fixed, then write in a separate field.
3. What for to you self::creating in boot() ? Create a separate method for adding an entry and move all the logic for adding this entry into it. You will call the method directly and pass data to it and you don’t have to keep in mind that somewhere else then something else happens on the event.
4. Further, if you use a separate field for the counter (and if you use id, then it is already auto-incrementing). Before saving, get the maximum value of the counter from the database ( https://laravel.ru/docs/v5/queries#%D0%B0%D0%B3%D1... ) add one.
5. Wrap the whole thing in a transaction https://laravel.ru/docs/v5/database#%D1%82%D1%80%D...
\DB::table($model->table) why? Vyzh inherited from the ORM model, work as with the ORM model. Herehttps://laravel.ru/docs/v5/eloquent#%D0%BF%D0%BE%D...

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question