How to Put Composite Keys in Models in Laravel 5

How I can put composite keys in models in Laravel 5?

You can't. Eloquent doesn't support composite primary keys.

Here's a Github issue regarding this.

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.

How to use composite primary key in laravel 8?

Laravel ships with the Eloquent ORM, and Eloquent doesn't support composite keys. If you're aiming to override Eloquent methods in order to support them, you'll need to override a lot of core methods to keep everything working properly.

Now, Eloquent isn't the only option to interact with the database. You can still use the Query Builder to perform your operations. But of course without the benefits of an ORM.

DB::table('response')->insert([
'tel' => '0123456789',
'number_str' => 1,
'view' => 0,
'channel' => 0,
]);

DB::table('response')
->where('tel', '0123456789')
->where('number_str', 1)
->get();

How to create composite key in ORM Eloquent Laravel 6.2

As per laravel, Eloquent does not support composite primary keys.
You can check this issue on laravel github repository here

If you really want to do this then you can override setKeysForSaveQuery of Model.php and set up your keys.

By Default:

protected function setKeysForSaveQuery(Builder $query)
{
$query->where($this->getKeyName(), '=', $this->getKeyForSaveQuery());

return $query;
}

$this->getKeyName() will return the primary key name and
$this->getKeyForSaveQuery() will return the value of the key.

This means that Eloquent always filter with only 1 field.

This which will be called once you perform a save action (UPDATE and DELETE) and what it does is that it generates a WHERE clause in the SQL.

for e.g.
Put this into that model that uses a composite primary key:

   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;
}


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);
}

If you use the Builder argument type in your setKeysForSaveQuery() definition then you'll also need to add the following to the top of the model:

use Illuminate\Database\Eloquent\Builder;


Related Topics



Leave a reply



Submit