【问题标题】:Laravel hasMany detachLaravel hasMany detach
【发布时间】:2015-12-16 05:25:10
【问题描述】:

我在 Eloquent 中遇到了关于删除子模型的问题: 在process2() 执行此操作时,我仍然有已删除的模型,这是不正常的。

型号

    namespace App\Models;

    use Illuminate\Database\Eloquent\Model;

    class Model1 extends Model
    {
        public function seasons() {
            return $this->hasMany('App\Models\Seasons', 'series_id', 'id');
        }
    }

服务

class Process {
    public function process1($model1Instance) {

        for($model1Instance->seasons() as $season) {
            if(//whatever//) {
                $season->delete();
            }
        }
    }
    public function process2($model1Instance) {
        for($model1Instance->seasons() as $season) {
            //At this point I still have the deleted instance
        }
    }
}

用法

$proc = new Process();
......
$proc->process1($model1Instance);
$proc->process2($model1Instance);

process1() 从父模型中删除一个模型时,我如何在process2() 中删除它?

尝试过/将尝试:

1.方法: $model1Instance->seasons()->detach($season); 但得到了:Call to undefined method Illuminate\Database\Query\Builder::detach()

2.另一个类 我可以创建另一个简单的类来存储这些,但我认为这不行,虽然我可以设置过滤季节但仍然必须使用 Model1 实例:

class Model1Copy {
    private $seasons;
    public function __construct($seasons) {
        $this->seasons = $seasons;
    }
}
  1. 尝试时致命:

    公共函数 process1($model1Instance) {

    for($model1Instance->seasons() as $season) {
        if(//whatever//) {
            $season->delete();
        } else {
        $childs[]=$season;
        }
    }
    $model1Instance->seasons = $childs
    

    }

  2. 我会创建自己的存储库来跳过 ORM 的行为,但这很令人沮丧,因为我必须重写所有查询才能删除一个实例...

【问题讨论】:

  • 我猜$season->delete() 调用失败了,因为该季节映射到 Model1。先分离再删除。
  • delete 方法工作正常,但在父模型中仍然可用,并在 process2() 中结束

标签: php eloquent laravel-5.1


【解决方案1】:

$model->seasons() 返回关系,而$model->seasons 返回映射到模型的季节集合。请尝试以下操作。

public function process1($model1Instance) {

    // Iterate over the collection
    for($model1Instance->seasons as $season) {
        if(condition) {
            $model1Instance->seasons()->detach($season); 
            $season->delete();
        }
    }

    $model1Instance->save();
}

此外,您正在迭代所有模型的所有季节,并删除满足某些条件的季节。一口气毁掉所有季节不是更有效吗?类似于以下内容:

$seasons = Season::where(condition)->get();
Season::destroy($seasons);

【讨论】:

  • 看似合理但得到:调用未定义的方法 Illuminate\Database\Query\Builder::sync()
  • 已更新。使用$model1Instance->season
  • 不幸的是我仍然有一个异常:调用未定义的方法 Illuminate\Database\Eloquent\Collection::sync()
  • 你确定你打电话给$model1Instance->seasons()->sync($childs)而不是$model1Instance->seasons->sync($childs)
  • 遗憾的是:$series->seasons()->sync($seasons);调用未定义的方法 Illuminate\Database\Query\Builder::sync() $series->seasons->sync($seasons);调用未定义的方法 Illuminate\Database\Eloquent\Collection::sync()
【解决方案2】:

试试这个

public function process1($model1Instance) {

    // Iterate over the collection
    for($model1Instance->seasons as $season) {
        if(condition) {
            $season->delete();
        }
    }

    $model1Instance->save();
}

【讨论】:

    【解决方案3】:

    删除hasMany条件的记录:

    $model1Instance->seasons()->where('condition', 'met')->delete();
    

    全部删除:

    $model1Instance->seasons()->delete();
    

    【讨论】:

      猜你喜欢
      • 2016-09-28
      • 1970-01-01
      • 1970-01-01
      • 2016-04-09
      • 1970-01-01
      • 1970-01-01
      • 2017-10-08
      • 2019-04-17
      • 2019-03-04
      相关资源
      最近更新 更多