删除具有关系的相关列的最佳方法

Posted

技术标签:

【中文标题】删除具有关系的相关列的最佳方法【英文标题】:Best way to delete related columns with relationships 【发布时间】:2018-11-11 07:05:37 【问题描述】:

例如,我们有 p_categories 表和 product 表。

p_categories 表是:

╔═══╦════════════╦═════════════╗
║   ║ id         ║ name        ║
╠═══╬════════════╬═════════════╣
║ 1 ║ 1          ║ tech        ║
║ 2 ║ 2          ║ food        ║
║ 3 ║ 3          ║ sport       ║
╚═══╩════════════╩═════════════╝

产品表是:

╔════╦═══════════════╦═════╗
║ id ║p_categories_id║name ║
╠════╬═══════════════╬═════╣
║ 1  ║ 1             ║phone║
╠════╬═══════════════╬═════╣
║ 2  ║ 2             ║spoon║
╠════╬═══════════════╬═════╣
║ 3  ║ 2             ║fork ║
╚════╩═══════════════╩═════╝

在我的 pcategory 模型中:

public function products()

    return $this->hasMany(Product::class, 'p_categories_id');

在产品模型中:

public function category()

    return $this->belongsTo(PCategory::class,'p_categories_id', 'id');

当我尝试删除技术类别时,必须同时删除 product table id=1, p_categories_id=1, name=phone 行。

我认为可能的解决方案:

1) 将列类型更改为级联。我读了一些帖子。人们大多不推荐这个。

2) 在类别模型中添加新功能

protected static function boot() 
parent::boot();
static::deleting(//something, i don't know how to make.); 

我需要用这种方法改变整个项目。因为一个都没有。我正在寻找最好的方法来做到这一点。我写了 2 个可能的解决方案,但我仍然不知道如何正确地制作它们。我希望我能解释一下自己,提前谢谢你

【问题讨论】:

快速建议,在products 表中使用categories_id 而不是p_categories_id...正如您所说,您可以选择使用 mysql 级联,我这样做(大部分时间),如果您阅读答案为什么不,请在此处分享。你写了“可能”的解决方案分享它们! 只是不要试图吃勺子 【参考方案1】:

要在模型中使用 Eloquent 事件,您可以执行以下操作:

static::deleting(function (self $category) 
    $category->products()->delete();
);

如果您还需要在产品上触发事件,则需要遍历产品并一一删除它们,例如

$category->products->each(function ($product) 
    $product->delete();
);

documentation 没有显示上述方法,而是倾向于使用Observers,但是它会显示您可以访问哪些模型事件。

【讨论】:

1 个类别在这种情况下可能有很多产品行。当我制作 $category->products->each->delete();需要 foreach 吗?它以这种方式工作对吗?我也有删除功能。 不需要Foreach,因为它是在幕后为你完成的,这是一个更高阶的消息laravel.com/docs/5.6/collections#higher-order-messages @AliÖzen 我已经更新了我的答案,试图让它更清晰。 谢谢,我会尽快尝试。【参考方案2】:

您必须使用数据库外键约束。对于使用 laravel 迁移的 make db,您可以使用

$table->foreign('p_categories_id')
      ->references('id')->on('p_categories ')
      ->onDelete('cascade');

见https://laravel.com/docs/5.5/migrations#foreign-key-constraints

【讨论】:

以上是关于删除具有关系的相关列的最佳方法的主要内容,如果未能解决你的问题,请参考以下文章

使用.Net Entity Framework 问题删除具有子关系的实体

如何测试依赖于具有关系的 Eloquent 模型的类?

检索具有 DISTINCT 列的 ActiveRecord 关系,采用具有相同关系的列排序的第一个实例 [重复]

数据库设计 - 管理这些关系的最佳方式

删除具有多对多关系的行

具有两个角色的帐户之间的关系的最佳实践是啥?