37

我正在尝试实现软删除概念。

这是我的对象:

class Post extends Eloquent {

    /**
     * The database table used by the model.
     *
     * @var string
     */
    protected $table = 'posts';
    protected $softDelete = true;

    ...

软删除已开启。

现在,如果我“删除”一个帖子,它会得到一个“deleted_at”时间戳:

描述

问题是,当我搜索或仅用于all()显示帖子时,软删除的项目会出现在那里。怎么了?

4

6 回答 6

57

有时,即使使用 eloquent 和,您也会获得soft deleted表条目。get()protected $softDelete = true;

所以为了避免这个问题,使用

...->whereNull('deleted_at')->get();

例如,此查询将获取包括软删除在内的所有行。

DB::table('pages')->select('id','title', 'slug')
                                   ->where('is_navigation','=','yes')
                                   ->where('parent_id','=',$parent_id)
                                   ->orderBy('page_order')
                                   ->get();

所以正确的方法是,

DB::table('pages')->select('id','title', 'slug')
                                   ->where('is_navigation','=','yes')
                                   ->where('parent_id','=',$parent_id)
                                   ->whereNull('deleted_at')
                                   ->orderBy('page_order')
                                   ->get();
于 2013-10-21T16:04:57.090 回答
37

使用 Eloquent 时,软删除功能有效如果您使用查询生成器查询结果,您最终会看到所有记录都被丢弃而不是被丢弃。

在 Laravel 4 的当前文档中并不清楚,但是看到软删除的概念只出现在Eloquent ORM - Soft Deleting下而不是在 Query Builder 下,我们只能假设:软删除仅适用于 Eloquent ORM

于 2013-08-11T01:06:18.933 回答
35

在 laravel 中使用软删除表和查询有一个小技巧:

当我们创建类似的东西时

$objCars = Car::where("color","blue");

系统执行如下操作:

SELECT
  *
FROM
  cars
WHERE
  deleted_at IS NULL
AND
  "color" = 'blue'

到现在为止还挺好。但是,当我们应用“orWhere”方法时,会发生一些有趣的事情

$objCars = Car::where("color","blue")->orWhere("color","red");

系统将执行类似的操作:

SELECT 
  * 
FROM
  cars
WHERE
  deleted_at IS NULL 
AND 
  "color" = 'blue'
OR
  "color" = 'red'

这个新查询将返回deleted_at 为空且颜色为蓝色或颜色为红色的所有汽车,即使deleted_at 不为空。这与其他查询的行为相同,更明确地显示了问题:

SELECT 
  * 
FROM
  cars
WHERE
  (
    deleted_at IS NULL 
  AND 
    "color" = 'blue'
  )
OR
  "color" = 'red'

为了避免这个问题,你应该改变传递闭包的“where”方法。像那样:

$objCars = Car::where(
  function ( $query ) {
    $query->where("color","blue");
    $query->orWhere("color","red");
  }
);

然后,系统将执行类似的操作:

SELECT
  *
FROM
  cars
WHERE
  deleted_at IS NULL
AND
  (
    "color" = 'blue' 
  OR
    "color" = 'red'
  )

最后一个查询,搜索所有已删除_at 为空且颜色可以是红色或蓝色的汽车,正如我们希望的那样。

于 2015-04-17T18:55:48.260 回答
8

我有同样的问题,这里没有任何帮助。

我的问题出在我的构造中,我忘了调用父构造函数:

public function __construct()
{
   parent::__construct();

   //Rest of my code
}

希望对某人有所帮助!

于 2016-10-19T23:53:48.190 回答
2

Laravel 5.2.44 将withoutTrashed()方法添加到SoftDeletingScope. 例如,您可以使用以下内容:

Post::withoutTrashed()->get();
于 2019-07-02T13:30:11.097 回答
1

在 Laravel 5.6 中测试过,您需要在模型中使用 SoftDeletes Trait

使用 Illuminate\Database\Eloquent\SoftDeletes;

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class Banners extends Model
{
    use SoftDeletes;
    //no need of this below line
    //protected $softDelete = true;
}

当你查询

$banners = Banners::where('status', 1)->get();

它不会返回软删除的数据。

于 2018-12-10T18:21:32.213 回答