Laravel 5 - 删除子模型数据

kat*_*son 0 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 |
+----+--------------+-----------------+----------+---------------+--------------+--------------------+----------+-------+--------+---------------------+---------------------+
Run Code Online (Sandbox Code Playgroud)

然后我有一个具有以下结构的 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 |
+----+--------------+-----------------+------------+---------------------+---------------------+
Run Code Online (Sandbox Code Playgroud)

这些模型中的关系非常简单。一个营销活动可以有多个营销活动类型,一个营销活动属于一个营销活动。

在 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.');
}
Run Code Online (Sandbox Code Playgroud)

现在虽然它不会引起太多问题,但我目前没有将任何 CampaignTypes 行设置为在其父 Campaign 已被删除的情况下被删除。

删除子数据而不实际删除它的最佳方法是什么?

谢谢

And*_*ker 5

您对 Campaign 模型所做的操作称为软删除,而 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();
}
Run Code Online (Sandbox Code Playgroud)

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

public function destroy(Campaign $campaign)
{
    $campaign->deleteAll();
}
Run Code Online (Sandbox Code Playgroud)

如果您决定为软删除实现 Laravel 约定(基本上向deleted_at模型添加属性并使用特征),那么模型deletingdeleted事件将被触发,您可以监听这些事件并在模型的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();
    });
}
Run Code Online (Sandbox Code Playgroud)

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

    public function destroy(Campaign $campaign)
    {
        $campaign->delete();
    }
Run Code Online (Sandbox Code Playgroud)