大怪兽/laravel-clearable

Laravel 框架 Eloquent 特性

v0.4.0 2022-10-17 03:11 UTC

README

英文 | 中文

LARAVEL ELOQUENT 特性

环境

  • laravel >= 9

安装

composer require biiiiiigmonster/laravel-clearable

简介

relation 非常强大,可以帮助我们管理复杂关系的数据。通常,在数据生命周期的最后阶段,"删除"行为受到较少的关注。我们在删除数据本身时,经常忽略关联模型数据的处理,这些残留数据也会因业务而受损。

此包可以帮助您轻松管理这些相关数据的删除关系,只需简单的定义即可。让我们试试吧!

用法

例如,User 模型相关的 Post 模型,也希望在 User 模型删除后,相关的 Post 模型也可以被删除

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{    
    /**
     * Get the posts for the user.
     *
     * @return HasMany
     */
    public function posts()
    {
        return $this->hasMany(Post::class);
    }
}

为了实现这一点,您可能需要将 BiiiiiigMonster\Clears\Concerns\HasClears 特性添加到您想要自动清除的模型中。在模型中添加了其中一个特性之后,将属性名称添加到模型的 clears 属性中。

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use BiiiiiigMonster\Clears\Concerns\HasClears;

class User extends Model
{
    use HasClears;
    
    /**
     * The relationships that will be auto-clear when deleted.
     * 
     * @var array 
     */
    protected $clears = ['posts'];
}

一旦将关系添加到 clears 列表中,在删除时会自动清除。

清除配置

自定义清除

有时您可能偶尔需要定义自己的清除逻辑,您可以通过定义一个实现 InvokableClear 接口的面实现这一功能。

要生成新的清除对象,您可以使用 make:clear Artisan 命令。我们将新的规则放在 app/Clears 目录中。如果此目录不存在,当您执行创建清除的 Artisan 命令时,我们将创建它

php artisan make:clear PostWithoutReleasedClear

一旦清除已创建,我们就可以定义其行为。一个清除对象包含一个方法:__invoke。此方法将确定关系数据是否被清除。

<?php

namespace App\Clears;

use BiiiiiigMonster\Clears\Contracts\InvokableClear;
use Illuminate\Database\Eloquent\Model;

class PostWithoutReleasedClear implements InvokableClear
{
    /**
     * Decide if the clearable cleared.
     *
     * @param Model $post
     * @return bool
     */
    public function __invoke($post)
    {
        return $post->status != 'published';
    }
}

一旦定义了自定义清除类型,您可以使用其类名将其附加到模型属性

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use BiiiiiigMonster\Clears\Concerns\HasClears;
use App\Clears\PostWithoutReleasedClear;

class User extends Model
{
    use HasClears;
    
    /**
     * The relationships that will be auto-clear when deleted.
     * 
     * @var array 
     */
    protected $clears = [
        'posts' => PostWithoutReleasedClear::class
    ];
}

使用队列

当我们需要清除的关系数据可能非常大时,使用 queue 来执行它是一个非常好的策略。

使其工作也很简单,将属性名称添加到模型的 clearConnection 属性中。

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use BiiiiiigMonster\Clears\Concerns\HasClears;
use App\Clears\PostWithoutReleasedClear;

class User extends Model
{
    use HasClears;
    
    /**
     * The clearable that will be dispatch on this connection queue.
     * 
     * @var string|null 
     */
    protected $clearConnection = 'redis';
}

一旦声明了 clearConnection,将使用队列连接执行 posts 的清除行为。

提示:即使您也可以将 protected $clearQueue 设置为字符串,它将在命名队列中运行。

运行时清除

在运行时,您可以像 append 一样指示模型实例使用 clearsetClears 方法

$user->clear(['posts' => PostWithoutReleasedClear::class])->delete();

$user->setClears(['posts' => PostWithoutReleasedClear::class])->delete();

PHP8 属性

PHP8 添加了 'Attribute' 功能,它提供了一种另一种配置形式,清除也为此做好了准备。

使用 Attribute 非常简单,我们定义了一个 #[Clear] 属性,只需关联方法即可。

namespace App\Models;

use BiiiiiigMonster\Clears\Attributes\Clear;
use BiiiiiigMonster\Clears\Concerns\HasClears;
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    use HasClears;
        
    /**
     * Get the posts for the user.
     *
     * @return HasMany
     */
    #[Clear] 
    public function posts()
    {
        return $this->hasMany(Post::class);
    }
}

同样,您可以在 #[Clear] 中设置 Custom Clear,甚至可以单独配置 clearQueue

#[Clear(PostWithoutReleasedClear::class, 'queue-name')]
public function posts()
{
    return $this->hasMany(Post::class);
}

提示:#[Clear] 将覆盖 protected $clears 中相应的配置。

支持的关联

数据 "删除" 通常是一个敏感的操作,我们不想重要数据通过任何关联声明 clear。因此,我们不支持 clearBelongsTo 关联中。

支持列表

  • HasOne
  • HasOneThrough
  • HasMany
  • HasManyThrough
  • MorphMany
  • MorphOne
  • 多对多关系
  • 多态对多关系

提示:当多对多关系多态对多关系的声明为清除时,被删除的是关联模型数据。

不支持列表

  • 属于
  • 多态属于

测试

composer test

许可证

MIT