Laravel 软删除所有坑及解决办法 - 持续更新

描述

很多时候,我们为了确保不丢失业务数据,会使用软删除的方法删除数据。
使用软删除的方法:
migrate文件:

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class Test extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('test', function (Blueprint $table) {
            $table->increments('id');
            // .. 等等其他字段
            $table->softDeletes();
        });
    }

}

Models:

<?php
use Illuminate\Database\Eloquent\Model;
class Test extends Model
{
    use SoftDeletes;

目前发现的问题及解决方法

问题1: 带唯一索引的软删除

代码模型和字段添加了软删除deleted_at,同时表又添加了唯一字段(如手机号),软删以后,别人重新添加这个唯一字段(如手机号)将无法添加数据,因为记录还在,只是deleted_at 赋了时间值 。

  • 方法一: 如果库表如果有唯一索引字段,插入时或查询是否有值时请自行调用withTrashed方法进行包含deleted_at 判断软删除是否有唯一索引字段值。
  • 方法二: 表字段不添加唯一索引, 通过业务控制唯一性。
  • 方法三: 唯一字段和软删除字段deleted_at 建立联合唯一(推荐)。
  • 方法四: 如果必须要使用唯一键控制又不联合deleted_at 唯一,放弃使用软删除。
  • 方法五: 参照下方评论,有很多牛人提出了解决办法和写了方法包。
本作品采用《CC 协议》,转载必须注明作者和本文链接
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 9

方法三 deleted_at为NULL时 会有问题

2年前 评论

emmm,你追加唯一判断不就得了。

案例一:添加

public function store(Request $request)

{

    $request->validate([

        'phone'=>'required|unique:users,phone,NULL,id,deleted_at,NULL',

    ]);

    // 后续逻辑

}

案例二:修改

public function update(Request $request, $id)

{

    $request->validate([

        'phone'=>'required|unique:users,phone,'.$id.',id,deleted_at,NULL',

    ]);

    // Write Code here

}
3年前 评论
zion_xayts_com 3年前
vimkid (楼主) 3年前
小李世界 3年前

为了让软删除功能可以使用唯一索引,我写了这个扩展包 博客:[扩展包] Laravel-softdeletes 让数据表支持唯一索引,用于替代内置...

这个软删方案是把软删数据放到另一张表,这样就不存在不能加唯一索引的问题了,并且用法上也几乎与内置的软删功能完全一致

3年前 评论
vimkid (楼主) 3年前

方法三 deleted_at为NULL时 会有问题

2年前 评论
xiaopi

方法三: 唯一字段和软删除字段 deleted_at 建立联合唯一 (推荐) 这种方式也有问题,因为deleted_at默认为null, 而mysql唯一索引对null不检查。最后结果就是deleted_at为null时,重复数据会插入。 请问有解决方法么

2年前 评论
深海之鲲 8个月前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!