【问题标题】:Why soft deleted entities appear in query results?为什么软删除的实体会出现在查询结果中?
【发布时间】:2013-08-05 03:44:58
【问题描述】:

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

这是我的对象:

class Post extends Eloquent {

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

    ...

软删除已开启。

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

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

【问题讨论】:

  • 您能否将代码发布到您删除对象的位置以及您要求它们在页面上显示的位置?
  • 谢谢,我已经解决了这个问题...我使用的是 Fluent 查询而不是 Eloquent,这就是这种行为的原因
  • 未来访问者:read this if you are using 4.2

标签: laravel laravel-4 eloquent soft-delete


【解决方案1】:

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

Post::withoutTrashed()->get();

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

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

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

      public function __construct()
      {
         parent::__construct();
      
         //Rest of my code
      }
      

      希望对某人有所帮助!

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

        • 我最初认为我的开发人员正在使用 Eloquent,因为查询首先提到了模型名称,就像 Laravel 的 Eloquent 区域中的文档是这样的:SomeModel:join('table2', 'column1', 'column2') 和 QueryBuilder 文档中的查询专门使用了我们没有使用的 DB::table。但是,如果您使用这种语法使用连接,那么它仍然会包含 softDeleted 数据,所以我不得不在我的查询中痛苦地添加 ->whereNull('table1.deleted_at')->whereNull('table2.deleted_at') (我希望有一个替代的 SoftDeletes 插件可以放入单独的归档表/模式中)
        【解决方案5】:

        在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 为空且颜色可以是红色或蓝色的汽车,正如我们希望的那样。

        【讨论】:

        • 这是一个更好更全面的答案。
        【解决方案6】:

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

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-09-08
          • 1970-01-01
          • 2017-08-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多