具有两个主键的 Laravel 模型更新 [重复]
Posted
技术标签:
【中文标题】具有两个主键的 Laravel 模型更新 [重复]【英文标题】:Laravel Model with Two Primary Keys update [duplicate] 【发布时间】:2016-07-19 19:47:13 【问题描述】:我正在尝试更新具有两个主键的模型。
型号
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'];
...
迁移
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');
);
这是应该更新 Inventory 模型的代码,但它没有。
$inventory = Inventory::where('user_id', $user->id)->where('stock_id', $order->stock->id)->first();
$inventory->quantity += $order->quantity;
$inventory->save();
我收到此错误:
Illegal offset type
我也尝试使用 updateOrCreate() 方法。它不起作用(我得到同样的错误)。
谁能告诉我们应该如何更新具有两个主键的模型?
【问题讨论】:
非法偏移类型,哪种类型?有行号吗?此查询中是否存在库存? 在 laravel/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php 第 2762 行出现 ErrorException。` /** * 获取 casts 数组。 * * @return array */ public function getCasts() if ($this->getIncrementing()) return array_merge([ $this->getKeyName() => 'int', // line 2762 ], $this- >铸件); 返回 $this->casts; ` 顺便说一下,这个库存存在。 粘贴完整的错误信息,以便我们可以在上下文中查看整个消息。 勾选这个github.com/laravel/framework/issues/5517 Laravel eloquent 不支持复合主键。 (旁注,您不能有两个主键。两个字段都是唯一主键的一部分) 完全错误pastebin.com/yaG0aZYM 【参考方案1】:我遇到过几次这个问题。您需要覆盖一些属性:
protected $primaryKey = ['user_id', 'stock_id'];
public $incrementing = false;
和方法(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);
记住这段代码需要引用 Eloquent Builder 类
use Illuminate\Database\Eloquent\Builder;
我建议将这些方法放在 HasCompositePrimaryKey
Trait 中,这样您就可以在任何需要它的模型中使用 use
它。
【讨论】:
awsm。谢谢!它确实应该在基础框架中得到支持...... 我用这段代码做了一个特征,现在我只需要在我的模型上use CompositeKeyModelHelper;
。谢谢!
将此添加到模型中,但它失败了。在调用此示例中列出的任何一个函数之前,似乎有东西在调用 Illuminate\Database\Eloquent\Model 中的 getKey(),导致抛出错误,因为它不期望属性数组。
好吧,你的权利,我是使用不同的构建器!我更正了它,但它仍然无法正常工作:Declaration of App\Lookup\CountryStats::setKeysForSaveQuery(Illuminate\Database\Eloquent\Builder $query) should be compatible with Illuminate\Database\Eloquent\Model::setKeysForSaveQuery(Illuminate\Database\Eloquent\Builder $query)
。我不明白为什么,因为它与Model
中的方法具有相同的参数和可见性。我还注意到setKeysForSaveQuery
在Model
中没有输入参数。
如果使用此解决方案的人正在使用软删除。您还需要覆盖 runSoftDelete pastebin.com/d3ED089R以上是关于具有两个主键的 Laravel 模型更新 [重复]的主要内容,如果未能解决你的问题,请参考以下文章