为什么软删除的实体出现在查询结果中?

时间:2013-08-04 08:31:28

标签: laravel laravel-4 eloquent soft-delete

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

这是我的目标:

class Post extends Eloquent {

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

    ...

已启用软删除。

现在,如果我'删除'帖子,它会获得'deleted_at'时间戳:

description

问题是,当我搜索或只是使用all()来显示帖子时,会在那里显示软删除的项目。有什么问题?

7 个答案:

答案 0 :(得分:42)

有时,即使使用了雄辩的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();

答案 1 :(得分:32)

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

当我们创建像

这样的东西时
$objCars = Car::where("color","blue");

系统执行类似的操作:

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

到目前为止,这么好。但是,当我们应用"或者"方法,有趣的事情发生

$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'

要避免此问题,您应该更改"其中"传递Closure的方法。像那样:

$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'
  )

这是最后一个查询,搜索所有有可能被删除的所有汽车以及颜色可以是红色或蓝色的汽车,正如我们希望的那样。

答案 2 :(得分:25)

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

目前尚不清楚Laravel 4的当前文档,但看到软删除的概念只出现在Eloquent ORM - Soft Deleting下而不是在查询生成器下,我们只能假设: 软删除仅适用于Eloquent ORM

答案 3 :(得分:5)

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

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

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

   //Rest of my code
}

希望能帮助别人!

答案 4 :(得分:0)

在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();

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

答案 5 :(得分:0)

Laravel 5.2.44向list2添加了withoutTrashed()方法。例如,您可以使用以下内容:

SoftDeletingScope

答案 6 :(得分:-1)

我用

Post::all()

我工作正常,我的意思是它不返回软删除的项目(标记为deleted_at时间戳的项目)。我正在使用Laravel 4。