【问题标题】:Cascading soft deletes with laravel 4 not working as expected使用 laravel 4 级联软删除无法按预期工作
【发布时间】:2014-08-14 17:03:57
【问题描述】:

我试图通过覆盖每个模型的delete() 函数来使级联软删除工作,我认为应该从Project 级联到VersionLink,但问题是它似乎没有完全做到这一点。想法是删除项目也会删除所有版本,这将删除所有链接并清除其缓存版本,但使用$this->versions()->delete(); 似乎并没有真正调用Version 模型中的delete() 方法.

关于如何按照我的预期工作有什么想法吗?

class Project extends Eloquent {

  protected $softDelete = true;

  public function versions()
  {
    return $this->hasMany('Version');
  }

  public function delete()
  {
    $this->versions()->delete();
    return parent::delete();
  }
}

class Version extends Eloquent {

  protected $softDelete = true;

  public function project()
  {
    return $this->belongsTo('Project', 'project_id');
  }

  public function links()
  {
    return $this->hasMany('Link');
  }

  public function delete()
  {
    $this->links()->delete();
    return parent::delete();
  }
}

class Link extends Eloquent {

  protected $softDelete = true;

  public function version()
  {
    return $this->belongsTo('Version', 'version_id');
  }

  public function delete()
  {
    Cache::forget($this->id);
    return parent::delete();
  }
}

【问题讨论】:

    标签: php laravel-4 eloquent soft-delete


    【解决方案1】:

    您想使用models events 而不是覆盖核心函数。引用文档:

    Eloquent 模型触发多个事件,允许您使用以下方法连接到模型生命周期中的各个点:creatingcreatedupdating已更新正在保存已保存正在删除已删除恢复恢复

    您想要做的是与这些挂钩。您可以通过多种方式做到这一点 (see the docs here)。下面以设置模型启动方式为例:

    public static function boot()
    {
        parent::boot();
    
        /**
         * Deleting
         * - Called before delete()
         * - Passes the instance in as param
         */
        static::deleting(function($project){
            // Get the project versions ids as an array
            $ids = $project->versions()->lists('id');
    
            // Delete the versions
            Version::whereIn('id', $ids)->delete();
        });
    }
    

    然后您可以在其他模型中执行相同的操作。希望对您有所帮助!

    【讨论】:

    • 不幸的是,这似乎不起作用,实际上似乎表现得像被覆盖的删除功能。当我从项目中调用 delete 时,版本被删除,但它永远不会到达链接,据我所知,它甚至从未真正进入版本 static::deleting 方法。任何想法为什么会这样?
    • 看来我不是唯一一个遇到这个问题的人:laravel.io/forum/…
    • 啊,我的错,是的,您需要使用查询来删除关系集合。更新了我的答案。
    【解决方案2】:

    $this->versions()->delete();Version::whereIn('id', $ids)->delete(); 在查询构建器上调用 delete(),而不是在 eloquent 模型上调用,这意味着模型事件不会被触发。相反,您应该这样做:

    foreach($this->versions as $version) { $version->delete(); }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-06-19
      • 2011-08-06
      • 1970-01-01
      • 2016-05-13
      • 2015-10-06
      • 1970-01-01
      • 2019-05-15
      • 1970-01-01
      相关资源
      最近更新 更多