Laravel 5 - 删除子模型数据

时间:2016-02-29 13:42:37

标签: laravel laravel-5

我有一个名为Campaign的模型,它采用以下结构

+----+--------------+-----------------+----------+---------------+--------------+--------------------+----------+-------+--------+---------------------+---------------------+
| id | campaignName | userId          | clientId | clientContact | contactEmail | campaignObjectives | acNumber | notes | active | created_at          | updated_at          |
+----+--------------+-----------------+----------+---------------+--------------+--------------------+----------+-------+--------+---------------------+---------------------+
|  1 | test         |               7 |       10 | Mr Fakes      | 12345        | sdfsdfsd           | 12345    |       |      0 | 2016-02-29 11:51:59 | 2016-02-29 13:51:28 |
+----+--------------+-----------------+----------+---------------+--------------+--------------------+----------+-------+--------+---------------------+---------------------+

然后我有一个具有以下结构的CampaignTypes模型

+----+--------------+-----------------+------------+---------------------+---------------------+
| id | campaignType | creativeArrival | campaignId | created_at          | updated_at          |
+----+--------------+-----------------+------------+---------------------+---------------------+
| 14 | Dynamic      | 2016-02-26      |          1 | 2016-02-23 16:00:01 | 2016-02-23 16:00:01 |
+----+--------------+-----------------+------------+---------------------+---------------------+

这些模型中的关系非常简单。 Campaign可以包含许多CampaignTypes,CamapignType属于Campaign。

在Campaign架构中,我有一个活动列。这是我用来删除广告系列的内容。所以destroy方法如下所示

public function destroy(Campaign $campaign)
{
    $campaign->update([
        'active' => false
    ]);

    Session::flash('flash_message', 'Campaign deleted');
    Session::flash('flash_type', 'alert-success');
    return Redirect::route('campaigns.index')->with('message', 'Campaign deleted.');
}

现在虽然它不会导致太多问题,但我目前没有将任何CampaignTypes行设置为在删除其父Campaign后删除。

在没有实际删除子数据的情况下删除子数据的最佳方法是什么?

由于

1 个答案:

答案 0 :(得分:3)

您对Campaign模型所做的操作称为soft delete,而Laravel实际上有一种很好的方法来处理它(查看链接)。但是,使用自己的约定进行软删除是完全有效的,因为当您将active列更改为0时,您目前正在这样做。无论您选择哪种方式,都没有自动执行此操作的Eloquent方法,因此你需要一些代码来修改父模型。

如果继续使用自定义软删除(就像现在一样),最简单的方法是在Campaign模型上制作自定义删除方法。此方法将更新记录(软删除它)并删除任何子项。您尚未指定是否希望子模型软删除或硬删除,但任何一个都很简单(如果您想要软删除它们,只需遍历所有并更新相关列)。

广告系列模型:

public function deleteAll() {
    $campaign = self::find($this->id);
    $campaign->update([
        'active' => false
    ]);

    //delete children, either hard or soft (use foreach loop on soft)
    $campaign->types()->delete();
}

然后您只需在控制器中调用该自定义方法。

public function destroy(Campaign $campaign)
{
    $campaign->deleteAll();
}

如果您决定实施Laravel惯例进行软删除(基本上向模型添加deleted_at属性并使用特征),那么模型的deletingdeleted事件将被触发,您可以listen for those并在模型的boot方法中回复它们。

广告系列模型:

protected static function boot() {
    parent::boot();

    static::deleting(function(campaign) {
        //delete children, either hard or soft (use foreach loop on soft)
        $campaign->types()->delete();
    });
}

然后每次在模型上调用delete()时都会触发,如下所示:

    public function destroy(Campaign $campaign)
    {
        $campaign->delete();
    }