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
