php 带有两个主键的 Laravel 模型更新

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36332005/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 00:46:28  来源:igfitidea点击:

Laravel Model with Two Primary Keys update

phplaravellaravel-5eloquentcomposite-primary-key

提问by Ugnius Malūkas

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).

我也尝试使用 updateOrCreate() 方法。它不起作用(我得到同样的错误)。

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

谁能告诉应该如何更新具有两个主键的模型?

回答by alepeino

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

记住这段代码需要引用 Eloquent Builder 类

use Illuminate\Database\Eloquent\Builder;

I suggest putting those methods in a HasCompositePrimaryKeyTrait so you can just useit in any of your models that need it.

我建议将这些方法放在HasCompositePrimaryKeyTrait 中,这样你就use可以在任何需要它的模型中使用它。