laravel 软删除

当模型被软删除时,它们并不会真的从数据库中被移除。而是会在模型上设置一个 deleted_at 属性并将其添加到数据库。如果对应模型被软删除,则deleted_at字段的值为删除时间,否则该值为空。

1.做一些设置

首先在模型类中要使用SoftDeletestrait,该trait为软删除提供一系列相关方法,具体可参考源码Illuminate\Database\Eloquent\SoftDeletes,此外还要设置$date属性数组,将deleted_at置于其中:

<?php 
    namespace App\Models; 

    use Illuminate\Database\Eloquent\Model; 
    use Illuminate\Database\Eloquent\SoftDeletes;  //这句必须要

    class Post extends Model {
    
     
        use SoftDeletes;  //这句必须要
        //...其他一些设置 
        protected $dates = ['delete_at']; 
    }

2.向数据库中的相应数据表添加delete_at字段

1>这里我们使用数据迁移来实现

php artisan make:migration alter_posts_deleted_at --table=posts

2>此时在database/migrations文件夹下会生成一个相应文件,更改如下

<?php 
    use Illuminate\Database\Schema\Blueprint; 
    use Illuminate\Database\Migrations\Migration; 

    class AlterPostsDeletedAt extends Migration {
    
     
        /** 
        * Run the migrations. 
        * 
        * @return void 
        */ 
        public function up() {
    
     
            Schema::table('posts', function (Blueprint $table) {
    
     
                $table->softDeletes(); 
            }); 
        } 
        ...//其它方法 
    }

3>再次运行命令 php artisan migrate ,发现数据库相应的数据表中已经有delete_at字段了

3.使用方法

在模型上调用 delete 方法时,deleted_at 字段将会被设置成目前的日期和时间。而且,当查找有启用软删除的模型时,被软删除的模型将会自动从所有查找结果中排除。

//在模型上调用delete方法
  $post = Post::find(6); $post->delete();
  //要确认指定的模型实例是否已经被软删除,可以使用 trashed 方法:  
   if($post->trashed()){
    
    
    echo '软删除成功!';
    dd($post);
  }else{
    
    
    echo '软删除失败!';
  }
 
  //查找被软删除的模型
  $flights = App\Flight::withTrashed() ->where('account_id', 1) ->get();
 
  //onlyTrashed 方法会只获取已被软删除的模型:
  $flights = App\Flight::onlyTrashed() ->where('airline_id', 1) ->get();
 
  //恢复单个已经被软删除的模型
  $flight = Flight::withTrashed()-find(1); //这里要注意如果被软删除直接find是查不到的
  $flight->restore();

  //恢复多个模型
  App\Flight::withTrashed() ->where('airline_id', 1) ->restore();
 
  // 强制删除单个模型实例...
  $flight->forceDelete();

  // 强制删除所有相关模型...
  $flight->history()->forceDelete();

在实际项目中,对数据频繁使用删除操作会导致性能问题,软删除的作用就是把数据加上删除标记,而不是真正的删除,同时也便于需要的时候进行数据的恢复。

要使用软删除功能,需要引入SoftDelete trait,例如User模型按照下面的定义就可以使用软删除功能:

<?php
namespace app\model;

use think\Model;
use think\model\concern\SoftDelete;

class User extends Model
{
    
    
    use SoftDelete;
    protected $deleteTime = 'delete_time';
}

deleteTime属性用于定义你的软删除标记字段,ThinkPHP的软删除功能使用时间戳类型(数据表默认值为Null),用于记录数据的删除时间。

可以支持defaultSoftDelete属性来定义软删除字段的默认值,在此之前的版本,软删除字段的默认值必须为null。

<?php
namespace app\model;

use think\Model;
use think\model\concern\SoftDelete;

class User extends Model
{
    
    
    use SoftDelete;
    protected $deleteTime = 'delete_time';
    protected $defaultSoftDelete = 0;
}

可以用类型转换指定软删除字段的类型,建议数据表的所有时间字段统一一种类型。

定义好模型后,我们就可以使用:

// 软删除
User::destroy(1);
// 真实删除
User::destroy(1,true);

$user = User::find(1);
// 软删除
$user->delete();
// 真实删除
$user->delete(true);

默认情况下查询的数据不包含软删除数据,如果需要包含软删除的数据,可以使用下面的方式查询:

User::withTrashed()->find();
User::withTrashed()->select();

如果仅仅需要查询软删除的数据,可以使用:

User::onlyTrashed()->find();
User::onlyTrashed()->select();

恢复被软删除的数据

$user = User::onlyTrashed()->find(1);
$user->restore();

软删除的删除操作仅对模型的删除方法有效,如果直接使用数据库的删除方法则无效,例如下面的方式无效(将不会执行任何操作)。

$user = new User;
$user->where('id',1)->delete();

grid中加回收站

<?php 
    namespace App\Models; 

    use Illuminate\Database\Eloquent\Model; 
    use Illuminate\Database\Eloquent\SoftDeletes;  //这句必须要

    class Post extends Model {
    
     
        use SoftDeletes;  //这句必须要
        //...其他一些设置 
        protected $dates = ['delete_at']; 
    }
protected function units_grid()
{
    
    
	$grid->actions(function ($actions){
    
    
            $actions->disableDelete();
            $actions->disableEdit();
            $actions->disableView();
            $back_url = $_SERVER["QUERY_STRING"];
            if (\request('_scope_') == 'trashed') {
    
    
                $actions->append('<a class="btn btn-sm btn-default grid-row-restore" data-id="'.$actions->getKey().'">恢复</a>');
            }else{
    
    
                $actions->append('<a class="btn btn-sm btn-default grid-row-delete" data-id="'.$actions->getKey().'">删除</a>');
            }
        });
        $grid->filter(function (Grid\Filter $filter){
    
    
            $filter->scope('trashed', '回收站')->onlyTrashed();
            $filter->disableIdFilter();
          	.....	
        });
 
        return $grid;
    }

猜你喜欢

转载自blog.csdn.net/xcbzsy/article/details/108467110