laravel软删除相关问题

Posted

技术标签:

【中文标题】laravel软删除相关问题【英文标题】:Questions related to soft delete in laravel 【发布时间】:2018-04-08 17:42:12 【问题描述】:

我有一些关于 laravel 中的软删除的问题。我已经搜索了它的作用和含义,关于软删除最容易理解的部分来自这句话

“当模型被软删除时,它们实际上并没有从您的 数据库。相反,在模型上设置了 deleted_at 属性,并且 插入到数据库中。如果一个模型有一个非空的deleted_at 值,模型已被软删除。启用软删除 模型,使用 Illuminate\Database\Eloquent\SoftDeletes 特征 模型并将 deleted_at 列添加到您的 $dates 属性:"

以下是我根据那句话提出的问题:

第一季度:

所以当我在我的代码中使用软删除时,当我尝试删除一些 数据,视图页面(blade.php)中的数据是否消失,而 数据库还包含这些数据吗?

第二季度:

我看到有些人使用静态::deleting 的东西,我没有 真的很明白这是怎么工作的?你能解释一下它的作用吗?谢谢 你

第三季度:

如何使用软删除来删除数据?我看到人们只是把 在他们的模型中添加一些东西而不是使用按钮,这是否意味着 您只能在模型中手动删除它,而不仅仅是 点击查看页面中的删除按钮?

【问题讨论】:

【参考方案1】:

澄清你的观点。 1. 当我们在代码中使用软删除时,deleted_at 将被更新为从 null 开始显示时间戳,因此在从项目中的任何位置查询该特定表中的数据时,雄辩的模型会自动返回deleted_at设置为NULL的数据,即不是软删除。

    人们使用一种叫做 static::deleting 的东西。 如果我以正确的方式理解您的问题,您可能会看到有点像这个例子:

    X-Model 类扩展了 Eloquent

    public function xy()
    
        return $this->has_many('XY_Model');
    
    
    // this is a recommended way to declare event handlers
    protected static function boot() 
        parent::boot();
    
        static::deleting(function($x)  
         // before delete() method call this
             $user->xy()->delete();
             // do the rest of the cleanup...
        );
    
    

    这是 Eloquent 事件删除记录的用例,该记录将使用“删除”事件进行清理。

    使用软删除删除数据

现在调用此函数后,您可以从表中软删除数据,如果模型中的关系维护正确,您还可以从其他依赖表中软删除数据。这实际上被称为级联效应。示例供您理解。 模型结构:

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use App\Utilities\Uuids;
use Illuminate\Database\Eloquent\SoftDeletes;
use Iatstuti\Database\Support\CascadeSoftDeletes;

class XFolder extends Model

    use SoftDeletes, CascadeSoftDeletes;
    use Uuids;
    protected $connection = 'XDB';
    protected $table = 'x_folder';
    protected $dates = ['deleted_at'];
    public $incrementing = false;
    protected $cascadeDeletes = ['XReference']; //related table with foreign keys
    protected $visible = [ 'id', 'x_id', 'xz_id', 'at_id', 'title', 'description', 'description', 'status', 'created_on' , 'is_active'];

    protected $fillable = [
     'x_id',
     'xz_id',
     'at_id',
     'title',
     'description',
     'status',
     'created_on',
     'is_active'
    ];

    public function XReference()
    
        return $this->hasMany('App\Models\XReference', 'x_id');
    

现在在控制器中你可以这样调用:

public function deleteData($id)
    
        $results = $this->getModel()->where('id', $id)->deleteData();
        return $results;
    

这将删除数据(级联格式软删除)。

【讨论】:

【参考方案2】:

问题 1

默认情况下:是。 这取决于您的查询。当使用软删除时,Laravel 会默认查询所有软删除的模型。当您还想获取软删除的模型时,您需要在查询中调用withTrashed() 方法。在此处阅读更多信息:https://laravel.com/docs/5.5/eloquent#querying-soft-deleted-models

要了解withTrashed() 的作用,您需要了解软删除的工作原理。软删除模型的工作原理是向您的数据库表中添加一个名为 deleted_at 的新列。它的值默认为null。当您软删除模型时,Laravel 会将当前时间戳放入该列。因此,该字段不再包含空值。

当使用软删除查询模型时,Laravel 会在查询中附加一个deleted_at is null 条件。调用 withTrashed() 方法会从查询中删除该条件。

查看default query modifier 和withTrashed method 的来源。


问题 2

那是事件。你可以调用它来告诉 Laravel,当这个事件发生时它应该执行那个特定的闭包。在您的示例中,它正在侦听“删除”事件。在此处查看更多信息:https://laravel.com/docs/5.5/eloquent#events


问题 3

您可以使用forceDelete() 方法完全删除软删除模型。请参阅此处的“永久删除模型”:https://laravel.com/docs/5.5/eloquent#querying-soft-deleted-models

【讨论】:

对于 withTrashed 方法有什么作用?资源只告诉我它仅用于关系目的,但你能向我解释更多吗?谢谢 所以当我创建软删除列时,我需要把它放在我所有其他有关系的表上吗?还是我只是把它放在连接到其他桌子的桌子上? 只针对要软删除的模型表。例如,如果您有 Posts 和 Comments,并且 cmets 是可软删除的,则只需将该列添加到 comments 表中。 父表呢?如果我把软删除那里会得到这个错误?“无法删除或更新父行:外键约束失败” 没有。你不会得到这样的错误,因为当你软删除它时,原始数据仍然存在于它的位置。最终删除数据时可能会出错,但这取决于您的数据库设置,与软删除无关。【参考方案3】:

Q1:那么当我在我的代码中使用软删除时,当我尝试删除一些数据时,视图页面(blade.php)中的数据是否会消失,而数据库仍然包含这些数据?

是的,如果您的模型使用softDelete,那么搜索查询将是这样的:Select * from table_name where delete_at = null

Q2:我看到有些人使用了一种叫做 static::deleting 的东西,我不太明白它是如何工作的?你能解释一下它的作用吗?

您可以使用:Modelname::destroy($id) 静态操作

它会破坏设置 $id 的模型对象。在销毁时,我的意思是:它会更新 deleted_at 列,因此应用程序会将其视为软删除对象

Q3:如何使用软删除来删除数据?我看到人们只是将一些东西放入他们的模型中而不是使用按钮,那么这是否意味着您只能在模型中手动删除它,而不仅仅是单击视图页面中的删除按钮?

我的一个项目示例:

我在合作伙伴屏幕上有一个删除按钮,路由到partner/ id /delete

在路线:Route::get('/partner/id/delete', 'PartnerController@deletePartner');

这个动作的结果:

public function deletePartner($partnerId = 0)

    if ($partnerId > 0)
        Partner::destroy($partnerId);
    

    return redirect("/partner");

所以:如果我单击删除按钮,它会检查 ID 是否已设置,然后“销毁它”(软删除)。删除后,它会重定向回合作伙伴

编辑:

对于问题3给出的例子,当你删除数据时,数据库数据是消失还是只有视图?

它只会从视图中消失。在数据库中,它将被存储为:

id name ... created_at       updated_at       deleted_at
1  foo  ... 2017-10-01 00:00 2017-10-01 00:00 NULL
2  bar  ... 2017-10-01 00:00 2017-10-01 00:00 2017-10-25 16:00

第一个是未删除的,第二个是软删除的对象,视图只会显示第一个

【讨论】:

对于问题3给出的例子,当你删除数据时,数据库数据是消失还是只有视图? 好的,请问您是否知道任何教程视频或网站,其中提供了有关如何逐步进行软删除的示例? 您可以从文档中学到很多东西。 This 是软删除部分。你也可以在Laracast 学到很多东西。他们有很多视频教程。 This 是关于软删除。 哈哈哈文档我已经读过了,但无论如何还是非常感谢你的帮助:)【参考方案4】:

Q1:所以当我在我的代码中使用软删除时,以及当我尝试删除时 一些数据,视图页面(blade.php)中的数据是否消失,而 数据库还包含这些数据吗?

是的。软删除填充数据库中的 deleted_at 列。从那以后,Eloquent 将不会检索这些数据(除非您要求)。如果您使用自定义 SQL 请求,则需要添加 WHERE deleted_at IS NULL

Q2:我看到有些人使用静态::deleting 的东西,我没有 真的很明白这是怎么工作的?你能解释一下它的作用吗?谢谢 你

我不是每天都用那个,但是你可以调用这个事件(见here)来自动删除相关的内容(例如,如果你删除一个用户,你也可以删除他的所有帖子。它是一种级联删除)

Q3:如何使用软删除来删除数据?我只看到人 将一些东西放入他们的模型中而不是使用按钮,所以这样做 这意味着您只能在模型内部手动删除它,而不是 只需点击查看页面中的删除按钮?

要使用软删除,您只需 $object->detroy($id)$myEloquentRequest->where(...)->delete() 如果您想强制进行真正的删除(因此条目将从数据库中明确删除),您可以使用$flight->forceDelete(); 有关更多信息,请参阅here。 您可以在任何地方进行删除。单击按钮将用户带到控制器中的 delete() 方法。您可以在那里删除或调用模型内的方法来触发删除(可能还有一些更复杂的删除,例如事件...)

【讨论】:

对于 deleted_at 列,我是否必须在我的数据库表中添加它?或者它会自动为我做这件事?或者只是把它放在我的模型中(我看到有些人把受保护的东西放在里面)? 你必须添加它。如果你使用迁移,你可以添加$table->softdeletes() 对不起,我现在很困惑,我想我应该把 deleted_at 列放在里面?为什么要软删除? 在您的数据库表中,您需要有一个“deleted_at”列,如 updated_at 或 created_at 列(如果您使用它们)。如果你在 Laravel 内部使用迁移文件,你可以使用上面的行来自动创建这个列。 哦,好吧,我想我明白你的意思了,是不是一旦你添加了$table->softdeletes(),deleted_at 列就会出现?【参考方案5】:

软删除意味着不删除数据库中的记录。所以我们处理一个标志 管理记录是否被删除。

让我用例子来解释更多:

在我们的记录中有很多用户,所以我们将一个字段 delete_at 添加到数据库中,并默认它的值为 null,因此它的记录不会被删除。

现在,当我们获取所有用户数据时,我们会像这样编写查询

Select * from user where delete_at = null

所以这个查询返回所有没有被删除的用户数据。

现在我们删除这个用户,所以当我们点击删除按钮时,我们创建自定义查询并使用当前日期时间更新这个用户 delete_at 字段

Update delete_at=date() where user_id = 1

所以现在这个记录是软删除。

现在我回答你的问题:

Q.1)软删除后没有数据不显示,因为当我们获取数据时,它会检查 delete_at 字段是否为空。

【讨论】:

哦,我明白了,那么有什么方法可以让我点击删除按钮,只有与该数据相关的视图消失,但数据库数据仍然存在 如果您使用软删除,它只更新 delete_at 字段值,但您的数据库数据保持不变 如果你喜欢我的回答,你可以接受这个回答,这样可以帮助其他人更好地理解

以上是关于laravel软删除相关问题的主要内容,如果未能解决你的问题,请参考以下文章

在 laravel 5.4 中检索软删除的用户帖子

Laravel - 软删除没有生效

Laravel 5.5 模型上的自定义软删除

Laravel“软删除”是不是需要 MySQL 上的索引?

laravel软删除和恢复删除用户

Laravel 软删除:model::onlyTrashed() 返回所有