我有一个名为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后删除。
在没有实际删除子数据的情况下删除子数据的最佳方法是什么?
由于
答案 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
属性并使用特征),那么模型的deleting
和deleted
事件将被触发,您可以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();
}