I had a model where the primary key was user_id instead of id.
It was a one-to-one profile table, so the user's ID made a natural key.
class Profile extends Model
{
protected $primaryKey = 'user_id';
protected $fillable = ['user_id', 'bio'];
}
After I created a record, something strange happened.
$profile = Profile::create([
'user_id' => 42,
'bio' => 'Hello world',
]);
$profile->user_id; // 0
The database had 42, exactly as expected.
But the model in memory said 0, and nothing threw an error.
By default, Eloquent assumes the primary key is an auto-incrementing integer.
So after the insert, it asks the database for the last inserted ID and writes that value back to the key on the model.
That's how a brand new model gets its id without another query.
In this case, the column wasn't auto-incrementing, so MySQL had no generated ID to report.
It returned 0, and Eloquent overwrote my 42 with it.
The fix is to tell Eloquent the key isn't auto-incrementing:
class Profile extends Model
{
protected $primaryKey = 'user_id';
public $incrementing = false;
protected $fillable = ['user_id', 'bio'];
}
Now Eloquent skips that step and keeps the value I passed in.
Here to help,
Joel
P.S. Catching a missing $incrementing before it turns into a confusing bug is exactly the kind of thing we look for in a code review.