laravel中与软删除相关的问题

Questions related to soft delete in laravel

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

"When models are soft deleted, they are not actually removed from your database. Instead, a deleted_at attribute is set on the model and inserted into the database. If a model has a non-null deleted_at value, the model has been soft deleted. To enable soft deletes for a model, use the Illuminate\Database\Eloquent\SoftDeletes trait on the model and add the deleted_at column to your $dates property:"

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

Q1:

So when I use soft delete in my code, and when I try to delete some data, does the data in the view page(blade.php) disappear while the database still contain those data?

Q2:

I saw some people using something called static::deleting, I don't really quite get how this work? Could you explain what it does? Thank you

Q3:

How do you delete data using soft delete? I saw people just putting some stuff into their model instead of using button, so does that mean you can only delete it manually inside the model instead of just clicking the delete button in the view page?

Soft delete means not delete records in database.So we handle one flag for manage records is deleted or not.

让我用例子来解释更多:

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

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

Select * from user where delete_at = null

所以这个查询return所有未删除的用户数据。

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

Update delete_at=date() where user_id = 1

所以现在这条记录被软删除了。

现在我来回答你的问题:

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

问题 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 and the withTrashed method 的来源。


问题 2

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


问题 3

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

Q1: So when I use soft delete in my code, and when I try to delete some data, does the data in the view page(blade.php) disappear while the database still contain those data?

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

Q2: I saw some people using something called static::deleting, I don't really quite get how this work? Could you explain what it does? Thank you

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

Q3: How do you delete data using soft delete? I saw people just putting some stuff into their model instead of using button, so does that mean you can only delete it manually inside the model instead of just clicking the delete button in the view page?

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

Q1: So when I use soft delete in my code, and when I try to delete some data, does the data in the view page(blade.php) disappear while the database still contain those data?

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

Q2: I saw some people using something called static::deleting, I don't really quite get how this work? Could you explain what it does?

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

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

Q3: How do you delete data using soft delete? I saw people just putting some stuff into their model instead of using button, so does that mean you can only delete it manually inside the model instead of just clicking the delete button in the view page?

我的项目之一的例子:

我在合作伙伴屏幕上有一个删除按钮,路由到 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 是否已设置,然后 "destroys it"(软删除)。删除后它重定向回合作伙伴

编辑:

For the example given in the question 3, when you delete the data, does the database data disappear or only the view?

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

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

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

澄清你的观点。 1. 所以当我们在代码中使用软删除时,deleted_at将更新为从null开始的时间戳,所以在查询数据时来自项目中任何地方的特定 table eloquent 模型将自动 return 其 deleted_at 设置为 NULL 的数据,即它不会被软删除。

  1. 人们在使用一种叫做 static::deleting 的东西。 如果我以正确的方式理解你的问题,你可能已经看到了类似这个例子:

    class X 模型扩展 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 事件删除记录的用例,该记录将使用 "deleting" 事件进行清理。

  2. 使用软删除删除数据

现在调用此函数后,您可以从 table 中软删除数据,如果模型中的关系得到适当维护,您还可以从其他相关 table 中软删除数据。这实际上被称为级联效应。例子让你明白。 模型结构:

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;
    }

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