1

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.

Anshul
  • 267
  • 1
  • 4
  • 13
  • 1
    Possible duplicate of [How I can put composite keys in models in Laravel 5?](https://stackoverflow.com/questions/31415213/how-i-can-put-composite-keys-in-models-in-laravel-5) – Rafael Beckel Mar 04 '18 at 13:57

4 Answers4

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
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
-1

in your migration use the following

$table->primary(['first', 'last']);

Ref Link: https://laravel.com/docs/5.4/migrations#indexes

Duy Anh
  • 750
  • 1
  • 7
  • 24