Laravel Model with Two Primary Keys Update

Laravel Model with Two Primary Keys update

I've run into this problem a couple of times. You need to override some properties:

protected $primaryKey = ['user_id', 'stock_id'];
public $incrementing = false;

and methods (credit):

/**
* Set the keys for a save update query.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @return \Illuminate\Database\Eloquent\Builder
*/
protected function setKeysForSaveQuery(Builder $query)
{
$keys = $this->getKeyName();
if(!is_array($keys)){
return parent::setKeysForSaveQuery($query);
}

foreach($keys as $keyName){
$query->where($keyName, '=', $this->getKeyForSaveQuery($keyName));
}

return $query;
}

/**
* Get the primary key value for a save query.
*
* @param mixed $keyName
* @return mixed
*/
protected function getKeyForSaveQuery($keyName = null)
{
if(is_null($keyName)){
$keyName = $this->getKeyName();
}

if (isset($this->original[$keyName])) {
return $this->original[$keyName];
}

return $this->getAttribute($keyName);
}

Remember this code needs to reference Eloquent Builder class with

use Illuminate\Database\Eloquent\Builder;

I suggest putting those methods in a HasCompositePrimaryKey Trait so you can just use it in any of your models that need it.

Unable to create multiple primary attributes

Those Keys may symbolise primary keys, foreign keys, unique columns or indexes.

You cannot have more than one primary key on a table.

Here is what I tried:
Diagram

php .\artisan make:model Employee -m
php .\artisan make:model Title -m
php .\artisan make:model Salary -m
class CreateEmployeesTable extends Migration
{
public function up(): void
{
Schema::create('employees', function (Blueprint $table) {
$table->bigIncrements('emp_no');
$table->string('first_name', 14);
$table->string('last_name', 16);
$table->date('birth_date');
$table->date('hire_date');
});
}
};
class CreateTitlesTable extends Migration
{
public function up(): void
{
Schema::create('titles', function (Blueprint $table) {
$table->unsignedBigInteger('emp_no');
$table->string('title', 50)->index();
$table->date('from_date')->index();

$table->foreign('emp_no')->references('emp_no')->on('employees');
});
}
};
class CreateSalariesTable extends Migration
{
public function up(): void
{
Schema::create('salaries', function (Blueprint $table) {
$table->unsignedBigInteger('emp_no');
$table->integer('salary');
$table->date('from_date')->index();

$table->foreign('emp_no')->references('emp_no')->on('employees');
});
}
};

Edit

Assuming that multiple key icons mean a composite key

class CreateEmployeesTable extends Migration
{
public function up(): void
{
Schema::create('employees', function (Blueprint $table) {
$table->bigIncrements('emp_no');
$table->string('first_name', 14);
$table->string('last_name', 16);
$table->date('birth_date');
$table->date('hire_date');
});
}
};
class CreateTitlesTable extends Migration
{
public function up(): void
{
Schema::create('titles', function (Blueprint $table) {
$table->unsignedBigInteger('emp_no');
$table->string('title', 50);
$table->date('from_date');

$table->foreign('emp_no')->references('emp_no')->on('employees');
$table->primary(['emp_no', 'title', 'from_date']);
});
}
};
class CreateSalariesTable extends Migration
{
public function up(): void
{
Schema::create('salaries', function (Blueprint $table) {
$table->unsignedBigInteger('emp_no');
$table->integer('salary');
$table->date('from_date');

$table->foreign('emp_no')->references('emp_no')->on('employees');
$table->primary(['emp_no', 'from_date']);
});
}
};

How to create two primary keys in one table using laravel migration?

Try this way, here is my e.g:

Schema::create("kitchen", function($table) {
$table->increments('id');
$table->integer('restaurant_id');
$table->string('name');
$table->unique(['restaurant_id', 'name']);
});

How to show data based on 2 primary keys in laravel?

Laravel does not support composite primary keys, check here. If you want to have a composite primary key you need to do all the work manually.

I would suggest having id as the primary key, and define company_id, year pair as unique key.

You can still ignore id as the primary key and use company_id, year pair as primary key, but as I mentioned that would be manual work. Check out routing and controller changes.

Route::get('master-cuti/{company_id}/{year}/show', CompanyMasterCutiController::class)->name('master-cuti.show');
 public function show($company_id, $year) {

$master_cuti = CompanyMasterCuti::where('company_id', $company_id)->where('year', $year)->first();

return view('master-cuti.show', compact('master_cuti'));

}

Laravel - Multiple primary key

Eloquent doesn't support multiple primary keys, but if you still want it, send an array to your primary(...).

So in your case:

Schema::create('doc_tag', function(Blueprint $table)
{
$table->integer('id_doc')->unsigned();
$table->integer('id_tag')->unsigned();

$table->primary(['id_tag', 'id_doc']);

$table->foreign('id_doc')
->references('id')
->on('doc');
$table->foreign('id_tag')
->references('id')
->on('tag');
});


Related Topics



Leave a reply



Submit