【问题标题】:Laravel 8 - can not set morphOne id when using Polymorphic RelationshipsLaravel 8 - 使用多态关系时无法设置 morphOne id
【发布时间】: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。但是当我创建 CostCostItem 时,如下所示:

$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


【解决方案1】:

在您问题的以下代码 sn-p 中,$cost = new Cost 是一个新实例,它不代表数据库中的现有记录,因此它没有 id 值 id=null

所以当你尝试通过关系更新或创建相关记录时,会报错。

由于它没有 id,任何通过关系创建相关记录的调用都会失败。

以 $cost 从数据库中获取一条新记录,然后通过关系调用更新或创建相关记录。

$cost = new Cost;
$cost->number = 'A00001';
$cost->note = 'test';
$cost->save();

$cost->fresh()->items()->attach($item, [
    'sku_id' => 1,
    'qty' => 10,
    'price' => 100,
]);

【讨论】:

    猜你喜欢
    • 2017-10-01
    • 2015-02-16
    • 1970-01-01
    • 2018-09-12
    • 2017-06-02
    • 2022-10-25
    • 1970-01-01
    • 1970-01-01
    • 2016-03-31
    相关资源
    最近更新 更多