You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel Eloquent:带版本控制的分类与产品关联及删除校验实现

嘿,我来帮你搞定这个Laravel里的分类删除校验问题!要实现删除Category时同时检查products和products_version表的关联记录,咱们可以分几步来做:

1. 先搞定基础关联

首先在你的Category模型里,先建立和Product的一对多关联,这是常规操作:

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class Category extends Model
{
    use SoftDeletes;

    // 你的fillable属性等其他配置
    protected $fillable = ['name', ...];

    // 关联Product模型
    public function products()
    {
        return $this->hasMany(Product::class);
    }
2. 加入版本表的校验逻辑

核心需求是要检查products_version表,咱们可以利用Laravel模型的deleting事件来拦截删除操作,这样不管是调用delete()还是批量删除,都会触发校验。直接在Category模型的booted方法里写逻辑就行:

protected static function booted()
    {
        static::deleting(function ($category) {
            // 先检查是否有活跃的关联产品
            if ($category->products()->exists()) {
                throw new \Exception('这个分类下面还有关联的产品,不能删除哦!');
            }

            // 再检查产品版本表中是否有该分类的记录
            $hasVersionedProducts = \DB::table('products_version')
                ->where('category_id', $category->id)
                ->exists();

            if ($hasVersionedProducts) {
                throw new \Exception('这个分类存在关联的产品版本记录,无法删除!');
            }
        });
    }
}
3. (可选)用Eloquent关联操作版本表

如果你觉得直接用DB门面不够优雅,也可以给products_version表建一个模型,比如ProductVersion:

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class ProductVersion extends Model
{
    // 指定表名,因为默认是复数形式,这里要对应你的表名
    protected $table = 'products_version';
    
    // 如果版本表没有created_at/updated_at字段,记得关掉timestamps
    public $timestamps = false;
}

然后在Category模型里添加这个关联:

public function productVersions()
{
    return $this->hasMany(ProductVersion::class, 'category_id');
}

这样,版本表的校验代码就可以改成更Eloquent的写法:

if ($category->productVersions()->exists()) {
    throw new \Exception('这个分类存在关联的产品版本记录,无法删除!');
}
4. 软删除的小提醒

如果你的Category也用了SoftDeletes,上面的deleting事件会在软删除和强制删除时都触发。要是你只想在强制删除的时候做校验,可以加个判断:

static::deleting(function ($category) {
    // 只有强制删除时才校验
    if ($category->isForceDeleting()) {
        if ($category->products()->exists()) {
            throw new \Exception('这个分类下面还有关联的产品,不能强制删除!');
        }

        if ($category->productVersions()->exists()) {
            throw new \Exception('这个分类存在关联的产品版本记录,无法强制删除!');
        }
    }
});

这样配置完之后,删除分类时就会自动校验两张表的关联记录啦!

内容的提问来源于stack exchange,提问作者Jelmer Bouman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 07:45:20