How to disable Laravel eloquent Auto Increment?

2020-07-20 00:15发布

问题:

I need an effective way to disable Laravel from auto incriminating the primary key of the table which I am going to insert data in.

Why? I don't check if there is any duplication between the DB and the inserted data so if there was any duplication I just handles it in a try-catch block.

The problem is if there was any failure Laravel counts it like I have inserted a row. So IDs column is not going to be in this order [1, 2, 3, etc], but in this [1, 4, 8, 20, etc].

I searched a lot about this issue and I have tried to use this line after the declaration of the class:

public $autoincrement = false;

Also

public $incrementing = false;

But they are not working.

I just want to use the AI of my DB. Not Laravel's one.

回答1:

if you wish to use a non-incrementing or a non-numeric primary key you must set the public $incrementing property on your model to false.

eg :

class UserVerification extends Model
{
    protected $primaryKey = 'your_key_name'; // or null

    public $incrementing = false;
}

in case of migration :

$table->integer('id')->unsigned(); // to remove primary key 
$table->primary('id'); //to add primary key

refer : https://laravel.com/docs/5.3/eloquent#eloquent-model-conventions



回答2:

Try public $incrementing = false;



回答3:

You have to declare your new primary key in your table migration file:

$table->primary('new_key_column');

Of course you have to disable autoincrement in your model as you did.



回答4:

There are 2 solutions to your problem. First one is, as you said, disable the increment column. To do that, just go to your migrations, and change

$table->increment('id)`

to

$table->integer('id')

It will remove the primary key, to set the primary key, just go to your Model file and add this:

protected $primaryKey = 'column_name';

Second solution is what I prefer. Whenever inserting, updating or removing a record and even sometimes reading a record, use laravel's DB transaction. Here is an example:

DB::beginTranscation();
try {
    $model = new Model;
    $model->column_name = $value;
    $model->save();
    DB::commit()
    return;
}
catch(exception $e) {
    DB::rollback();
    return;
}

This approach is better than remove the auto increment. But now it's upto you to choose.



回答5:

You can do something like below

Table: author

Columns: id, name, active

class Author extends Model
{
    /**
     * Configure the Model variables
     *
     */
    protected $table = 'author';
    protected $primaryKey = 'id';
    protected $fillable = ['name', 'active']; // eloquent Will use only these columns as you are mentioning them as fillable.

    public static function saveAuthor($data) {
         $author = Author::firstOrNew(['name' => $data['name']]);

            $author->name = $data['name'];
            $author->active = 1;
            $author->save();
    }
}

Here in fillable you define the columns that you want to change or update through model. Rest fields behaviour will take according to mysql definition.

I hope this will help you.



回答6:

This is an example for table created its name site_rules and this is the migration file which i add the following line to make id primary and auto incremented
//add this line to make id auto incremented from a specified value DB::statement("ALTER TABLE site_rules AUTO_INCREMENT = 1;"); and this is the migration file code :

<?php

 use Illuminate\Support\Facades\Schema;
 use Illuminate\Database\Schema\Blueprint;
 use Illuminate\Database\Migrations\Migration;
class SiteRules extends Migration
{
/**
 * Run the migrations.
 *
 * @return void
 */
public function up()
{
    Schema::create('site_rules', function (Blueprint $table){
        $table->increments('id');
        $table->string('name_ar');
        $table->string('name_en'); 
        $table->timestamps();
    });
    //add this line to make id auto increment from a specified value 
    DB::statement("ALTER TABLE site_rules AUTO_INCREMENT = 1;");
}

/**
 * Reverse the migrations.
 *
 * @return void
 */
public function down()
{
    Schema::dropIfExists('site_rules');
}
}

Try it



回答7:

Sorry for taking your time guys, The issue is if we tried to save any record in MYSQL whether it returned success or failure for any reason (like for duplication in my case),

MYSQL counts that the auto increment number was booked and any other coming record is not going to take it because of there may be more than an insertion process on the DB in the same time and waiting to know if the auto incrementally number is booked or not will cost MYSQL its speed.

So it is not a Laravel issue, its a MYSQL one.

I hope that it may help others.

Thank you all...