【发布时间】:2020-12-01 02:06:25
【问题描述】:
我使用 Laravel 8 的 Polymorphic Relationships 声明 Models,如下所示:
Item:
class Item extends Model
{
protected $table = 'items';
public function costs()
{
return $this->belongsToMany(Receive::class, 'cost_item', 'cost_id', 'item_id')
->withPivot([
'id',
'cost_id',
'item_id',
'sku_id',
'qty',
'price',
])
->withTimestamps()
->using(CostItem::class);
}
}
Movement:
class Movement extends Model
{
protected $table = 'movements';
public function movable()
{
return $this->morphTo();
}
}
Cost:
class Cost extends Model
{
protected $table = 'costs';
public function items()
{
return $this->belongsToMany(Item::class, 'cost_item', 'cost_id', 'item_id')
->withPivot([
'id',
'cost_id',
'item_id',
'sku_id',
'qty',
'price',
])
->withTimestamps()
->using(CostItem::class);
}
}
CostItem:
class CostItem extends Pivot
{
protected $table = 'cost_item';
public function movement()
{
return $this->morphOne(Movement::class, 'movable');
}
public function syncMovement()
{
$this->movement()->updateOrCreate([], [
'sku_id' => $this->sku_id,
'qty' => $this->qty,
'price' => $this->cost,
]);
}
protected static function booted()
{
static::created(function ($model) {
$model->syncMovement();
});
}
}
我在CostItem 中使用created 事件,我想在创建CostItem 时将CostItem 数据同步到Movement。但是当我创建 Cost 和 CostItem 时,如下所示:
$cost = new Cost;
$cost->number = 'A00001';
$cost->note = 'test';
$cost->save();
$cost->items()->attach($item, [
'sku_id' => 1,
'qty' => 10,
'price' => 100,
]);
我总是得到错误:
Next Illuminate\Database\QueryException: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'movable_id' cannot be null (SQL: insert into `movements` (`movable_id`, `movable_type`, `sku_id`, `quantity`, `price`, `remaining`, `updated_at`, `created_at`) values (?, App\Models\ReceiveItem, 1, ?, 100, ?, 2020-12-01 10:27:03, 2020-12-01 10:27:03))
我该如何解决这个问题?还是我写错了什么? 任何帮助表示赞赏。谢谢。
【问题讨论】:
-
在syncMovement方法中不应该是
$this->movement()->updateOrCreate() -
@Donkarnash 我已经改变了,但我仍然遇到同样的错误......
-
updateOrCreate 的第一个参数是一个空数组,这意味着它总是会创建对吗?
-
@Donkarnash 是的。但就我而言,我只是创建了新的 CostItem,并没有更新它。
-
试试
$cost->fresh()->items()->attach(...)。由于在该行上面的代码中您实例化了 $cost = new Cost 并且 $cost->save() 返回一个布尔值,因此 $cost 仍然持有未持久的实例。当您尝试在未访问的实例上附加关系时,由于 id 不存在,它会出错
标签: php laravel eloquent laravel-8