I once read an article about changing the primary key column id of to the name of your model. So if database was named “items” , your primary id shouldn’t just be named “id” but “item_id”. Building things from scratch, this came in handy. Especially when debugging and joining tables. When you saw an error like “ambiguous name column” and you joined 3 tables, you needed to specify each table name with it’s id. And that’s just one example.
Since I started developing in Laravel I wanted to do this too.
My migration file would look like this
public function up()
{
Schema::create('items', function (Blueprint $table) {
$table->id('item_id');
$table->string('item_name');
$table->timestamps();
});
}
As you can see I added ”item_id” inside of the usual $table->id(”) . Running the migration would rename primary key id to item_id. You would only see the problem when trying to route to the record and most likely get the following error:
Missing required parameter for [Route: item.edit] [URI: items/edit/{item}] [Missing parameter: item].
Or when trying to fetch the record you would get:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'id' in 'where clause' (SQL: select * from `items` where `id` = 1 limit 1)
The Problem:
By default Laravel is searching for the id column, but cannot find it because we renamed the primary key column to item_id
The Solution
You have to (re)define the primary key in the model. In this case my model name is Item, so in app\Models\Item.php you have to add the following:
protected $primaryKey = 'item_id';
The models would then be :
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Item extends Model
{
use HasFactory;
protected $primaryKey = 'item_id';
protected $fillable = [
'item_id',
'item_name',
];
}
Laravel knows the primary key is now changed to item_id and would then change it’s query .
So by default Laravel would do something like this
select * from `items` where `id` = 1 limit 1
but after redefining the primary key, Laravel will now do this
select * from `items` where `item_id` = 1 limit 1
So that’s how I solved this particular problem and I hope it helps you if you were somehow Googling this.
Happy Programming!