【问题标题】:Cloning model with hasMany related models in Laravel 5.3在 Laravel 5.3 中使用 hasMany 相关模型克隆模型
【发布时间】:2016-10-01 22:52:34
【问题描述】:

(看起来我解决了我自己的问题,如果有人可以回答 Update 1 中的问题并检查我自己的解决方案以解决 Update 2 中的问题。谢谢.) 尝试使用相关项目克隆发票模型。 收到 Call to undefined method Illuminate\Database\Query\Builder::associate() 错误。 非常感谢任何帮助!

Invoice.php

public function items(){
    return $this->hasMany('App\Item');
}

Item.php

public function invoice(){
    return $this->belongsTo('App\Invoice');
}

InvoiceController.php

public function copy(Invoice $invoice){
    $copy = $invoice->replicate(['number']);
    foreach($invoice->items as $item) $copy->items()->associate($item);
    $copy->push();
    return redirect('/invoices/' . $copy->id . '/edit')->with('alerts', ['Invoice has been copied']);
}

更新 1

我想,我想通了。在子节点上调用 saveMany 之前,应首先保存父克隆模型以接收 ID。看起来push 方法也不能在这里使用。 我还是很疑惑,为什么我不能在这种场景下使用associatepush 方法...

更新 2

原来这个方法不是创建克隆项目,而是更新它试图克隆的项目,这很奇怪......我所做的是循环内的replicate项目(复制不存在于关系中比如belongsTo)。所以我的最终代码是:

public function copy(Invoice $invoice){
    $copy = $invoice->replicate(['number', 'url_key']);
    $copy->url_key = strtolower(str_random(8));
    $copy->save();
    foreach($invoice->items as $item) $copy->items()->save($item->replicate(['type_id']));
    return redirect('/invoices/' . $copy->id . '/edit')->with('alerts', ['Invoice has been copied']);
}

【问题讨论】:

    标签: php laravel laravel-5 eloquent belongs-to


    【解决方案1】:

    您需要调用 save() 而不是 associate()

    $copy->items()->save($item);
    

    saveMany() 为模型集合在内部调用 save()

    $copy->items()->saveMany($invoice->items);
    

    【讨论】:

    • 在发帖之前我确实尝试过使用save 方法,但看起来这种方法无法将项目与发票“关联”。 Integrity constraint violation: 1048 Column 'invoice_id' cannot be null (SQL: update items` 设置 invoice_id = , updated_at = 2016-10-01 00:00:00 其中id = 1)`
    • 另外,如果我将您的第二种方法与saveMany 一起使用,则会引发另一个错误:Method saveMany does not exist. 看起来您的第二种方法中有错字,应该是:$copy->items()->saveMany($invoice->items);?在这种情况下,与第一种方法相同的错误...
    • 我也尝试将 NULL 设置为 invoice_id 字段的默认值,并且程序能够完成,但正如我所怀疑的,它只是创建了具有 NULL invoice_id 字段的项目(我想知道这个字段是否会在之后填充)。
    • saveMany 有一个错字,现在它会存在。您还应该使用新发票的 ID 更新项目的副本,除非您希望副本指向旧发票。
    • 我已经在我提到不存在的方法的同一评论中注意到了类型。另外,我认为以$copy->items()->save() 形式进行克隆的全部目的是为了不手动更新 ID 为 $copy 的项目。
    猜你喜欢
    • 2018-06-30
    • 1970-01-01
    • 2012-02-19
    • 1970-01-01
    • 2017-05-30
    • 2012-10-19
    • 1970-01-01
    • 2021-11-14
    • 2015-03-12
    相关资源
    最近更新 更多