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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With