Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel Model with Two Primary Keys update [duplicate]

I'm trying to update Model which has two primary keys.

Model

namespace App;  use Illuminate\Database\Eloquent\Model;  class Inventory extends Model {     /**      * The table associated with the model.      */     protected $table = 'inventories';      /**      * Indicates model primary keys.      */     protected $primaryKey = ['user_id', 'stock_id']; ... 

Migration

Schema::create('inventories', function (Blueprint $table) {     $table->integer('user_id')->unsigned();     $table->integer('stock_id')->unsigned();     $table->bigInteger('quantity');      $table->primary(['user_id', 'stock_id']);      $table->foreign('user_id')->references('id')->on('users')         ->onUpdate('restrict')         ->onDelete('cascade');     $table->foreign('stock_id')->references('id')->on('stocks')         ->onUpdate('restrict')         ->onDelete('cascade'); }); 

This is code which should update Inventory model, but it doesn't.

$inventory = Inventory::where('user_id', $user->id)->where('stock_id', $order->stock->id)->first(); $inventory->quantity += $order->quantity; $inventory->save(); 

I get this error:

Illegal offset type 

I also tried to use updateOrCreate() method. It doesn't work (I get same error).

Can anyone tell how Model with two primary key should be updated?

like image 447
Ugnius Malūkas Avatar asked Mar 31 '16 11:03

Ugnius Malūkas


1 Answers

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.

like image 184
alepeino Avatar answered Sep 26 '22 02:09

alepeino