We want to implement Composite primary key with Eloquent ORM and Laravel 5 for http://www.mbarendezvous.com/ I understand it is not currently supported by Eloquent . Please suggest what should be the best alternative for the same.
Asked
Active
Viewed 8,865 times
4 Answers
10
I use the following code. It overwrites the original Model.php methods and takes all the primary keys into consideration. Put this into that model that uses a composite primary key:
protected function getKeyForSaveQuery()
{
$primaryKeyForSaveQuery = array(count($this->primaryKey));
foreach ($this->primaryKey as $i => $pKey) {
$primaryKeyForSaveQuery[$i] = isset($this->original[$this->getKeyName()[$i]])
? $this->original[$this->getKeyName()[$i]]
: $this->getAttribute($this->getKeyName()[$i]);
}
return $primaryKeyForSaveQuery;
}
/**
* Set the keys for a save update query.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @return \Illuminate\Database\Eloquent\Builder
*/
protected function setKeysForSaveQuery(Builder $query)
{
foreach ($this->primaryKey as $i => $pKey) {
$query->where($this->getKeyName()[$i], '=', $this->getKeyForSaveQuery()[$i]);
}
return $query;
}
EDIT: Do not forget to add the following in your model class, otherwise this won't work.
public $incrementing = false;

Peter Matisko
- 2,113
- 1
- 24
- 47
-
2This worked, once I put in `public $incrementing = false;` at the top of my model. – Skrrp Aug 06 '17 at 14:59
-
1
-
I also had to add `protected $primaryKey = ['key1','key2','key3'];` since I had three different keys and none of them is `id`. – Zariweya Aug 02 '18 at 09:34
1
You can override the setKeysForSaveQuery
method from laravel's Model class. You can change this method to:
/**
* Set the keys for a save update query.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @return \Illuminate\Database\Eloquent\Builder
*/
protected function setKeysForSaveQuery(Builder $query)
{
$query->where($this->getKeyName(), '=', $this->getKeyForSaveQuery());
$query->where('secondKeyName', $this->secondKeyName); // <- added line
return $query;
}

dctucker
- 679
- 5
- 12

Ron van Asseldonk
- 1,275
- 2
- 11
- 18
-1
You can override the save() method on your class that extends Model that has composite keys like the following:
public function save(array $options = array())
{
$query = $this->newQueryWithoutScopes();
// MY MODEL SPECIFIC FIX
$query->where('OTHER_ID', '=', $this->OTHER_ID);
// END MY FIX
// the rest of the standard model->save() code is here but I cut it out for brevity.
// Use what is in Model.php already.
}
I saw this solution here: https://github.com/laravel/framework/issues/5517

Murilo
- 580
- 5
- 21
-
This will perfectly for an update, but it will not work correctly when the model will be created. – Ron van Asseldonk Jun 29 '17 at 09:41
-1
in your migration use the following
$table->primary(['first', 'last']);

Duy Anh
- 750
- 1
- 7
- 24
-
2This will add an index and constraints. But eloquent will still not work with composite keys. – Thijs Steel Jul 19 '17 at 08:52