webguy23's avatar

Eloquent displays wrong random ID

When I'm trying to create a new record in DB, Eloquent displays wrong ID but it saves normal ID to database.

To show you an example, I've generated a new simple standard Laravel model "Country", so the table is completely new and empty. When I do this in Tinker:

app(Country::class)->create(['country' => 'Germany']), it returns this:

App\Models\Country {#6820
    name: "Germany",
    updated_at: "2025-01-06 04:29:02",
    created_at: "2025-01-06 04:29:02",
    id: 71558,
  }

So, the problem is this ID 71558 which looks random. But ID in database is 1 as it supposed to be.

When I'm trying to create another model (like User) in Tinker, I get ID 71559 (the previous 71558 plus 1) but in database it's 22 as it supposed to be because I already have 21 users in the table.

So, it looks like Eloquent models show some ID which is common for all models and it's incrementing but it looks completely random. But then Eloquent saves normal ID to database.

I've never seen anything like this in any Laravel project. Do you guys have any idea why this is happening?

0 likes
20 replies
skiarsi's avatar

by default it's not posible, but maybe AUTO_INCREMENT is not reset after you delete some records in your database. so it's good to reset it by run ALTER TABLE countries AUTO_INCREMENT = 1; and then again run tinker and make new row. please share here what you got.

Tray2's avatar

If you are using auto_increment on the ID column, then it uses the next number in sequence.

$table->id();

The first record gets the id of 1, the second 2 and so on. If records are deleted, it still continues with the sequence, it does not start over.

  1. Deleted

Show us the code for your migration, and the code you use to create the record in the database.

1 like
webguy23's avatar

I hear you guys but the problem is not with the auto increment.

I've created a completely new table, so ID should be 1 and it is 1 in the table, but in Eloquent model it's 71558. The model and migration are the standard ones, created with php artisan make:model Country -m

Tray2's avatar

@webguy23 Like I said, show your code.

The id comes from the database, not from Eloquent, unless you somehow override that, which you really shouldn't.

1 like
webguy23's avatar

@Tray2 I didn't override it, it's a standard Eloquent model without any modifications accept adding protected $fillable = ['name']; line. And the problem is ID in database and ID in a model are different.

Tray2's avatar

@webguy23 So you are saying that the id in the database is 9 and the result you get back say 652?

What RDBMS are you using?

And once again show the code you use.

1 like
webguy23's avatar

@Tray2

I'm using standard MySQL the one is in Laravel Sails.

In Tinker I do this, it creates a new record in brand new countries table with ID = 1, but the object shows 71571

> app(App\Models\Country::class)->create(['name' => 'Canada'])
= App\Models\Country {#6812
    name: "Canada",
    updated_at: "2025-01-06 13:06:31",
    created_at: "2025-01-06 13:06:31",
    id: 71571,
  }

Model App\Models\Country

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Country extends Model
{
    protected $fillable = ['name'];
}

The up method in migration

    public function up(): void
    {
        Schema::create('countries', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->timestamps();
        });
    }
Tray2's avatar

@webguy23 Which version of Laravel are you using?

And what do you get if you do this?

$country = app(App\Models\Country::class)->create(['name' => 'Canada']);
echo $country;

Also what happens if you run

php artisan migrate:fresh and then do the same thing?

1 like
webguy23's avatar

@Tray2 Laravel 10.48.22

After migrate:fresh it works properly which is a step forward, but the problem is I can't do this on live server, cause there is a lot of data there. So, I need to find the reason why this is happening.

When I do echo, I get this

{"name":"Canada","updated_at":"2025-01-06T15:21:27.000000Z","created_at":"2025-01-06T15:21:27.000000Z","id":71582}
Tray2's avatar

@webguy23 Then the remote db server is on the id in the sequence.

Run this query on your production server, it will give the next id for the sequence of the given table.

SELECT AUTO_INCREMENT
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = "yourDatabaseName"
AND TABLE_NAME = "yourTableName"
1 like
webguy23's avatar

@Tray2 I ran it on live database (local DB doesn't have the issue because of migrate:fresh) and it returns 11 for a specific table. The table last records are 8, 9, 13, 15. But when I create something in the table, the ID in 16 in the database and 19066356 in the object returned by Eloquent create method.

jjoek's avatar

@webguy23 Still on tinker when you try and fetch the given record after you create what do you get? do you still get the random id or does this come with the correct id now?

If this comes with the same random ID, this could be something within eloquent that is transforming your ids on fetch which is weird

If this gets you the correct ID from the database on fetch, this could then be some disconnect between when the record saving and immediate fetching

webguy23's avatar

@jjoek when I get the record by name, I get correct ID. The problem is this behavior (random ID when record just created) ruins a lot of things in the app.

Sinnbeck's avatar

If it also happens in production, I can assume it isn't due to sail as that is dev only. So it must be code.

Update all dependencies. Or make a new project and copy over files until it happens in that app as well

1 like
Sinnbeck's avatar

Maybe you either have an event or something else that is overwriting the creation process. Or overwriting the mysql driver in a service provider. Hard to say without seeing your code

1 like
webguy23's avatar

@Sinnbeck you were right, the problem was in the code in a service providers (I've added the code below). Thank you for pointing me.

Should I mark your answer as solution or should I mark my comment with the code? I'm not sure how this should be done on Laracasts forums in this situation.

Merklin's avatar

Why nobody says, that there is no primary set in the migration? Shouldn't it be like:

 public function up(): void
    {
        Schema::create('countries', function (Blueprint $table) {
            $table->id()->primary();
            $table->string('name');
            $table->timestamps();
        });
    }
webguy23's avatar

I found the issue. The problem is this code in a service provider which supposed to log db queries.

        DB::listen(function ($query) {
            if (!str_contains($query->sql, 'log_')) {
                DB::table('log_db_queries')->insert([
                    'request_id' => config('app.request_id'),
                    'sql' => substr(Str::ascii($query->sql), 0, 2000),
                    'bindings' => substr(Str::ascii(json_encode($query->bindings)), 0, 2000),
                    'time' => $query->time
                ]);
            }
        });

Thank you for helping guys.

Please or to participate in this conversation.