在父更新时删除一个集合

Deleting one of a collection on parent update

我试图在更新时删除(或创建)模型关联对象。每个栏都有几个水龙头。当您创建小节时,会创建这些拍子对象,您可以更新该数量,并根据需要创建或删除其他拍子。

本来我只是想这样使用pop:

        $taps=$bar->taps;
        if ( $taps_old < $taps_new){
            for ($i = $taps_old; $i < $taps_new; $i++) {
                $tap = Growlertap::create(['growlerstation_id' => $id]);
            }
        }
        elseif ($taps_old > $taps_new) {
            for ($i = $taps_new; $i < $taps_old; $i++) {
                $taps->pop();
            }

这不起作用,但不会给我错误。我知道 if 语句工作正常,因为下面的代码有效:

        elseif ($taps_old > $taps_new) {
            for ($i = $taps_new; $i < $taps_old; $i++) {
                Beertap::where('bar_id', '=', $id)->first()->delete();
            }
        }

这似乎不是最简单的写法。有没有更好的写法?

顺便说一下,对于那些想知道的人,这是我控制器中的更新功能。

这应该可行不幸的是这不起作用,因为 DELETE 语句不支持偏移量。

Beertap::where('bar_id')->skip($taps_new)->delete();

因此它会跳过您想要保留的任意数量的点击,并删除其余的。如果删除哪些行很重要,您可能想使用 orderBy

更新

现在应该完全可以了。首先获取所有要从集合中删除的 ID,然后使用 一个查询

删除它们
$idsToDelete = $taps->slice($taps_new)->modelKeys();
Beertap::destroy($idsToDelete);

更新 2

您也可以优化创建过程(以便在单个查询中完成)

$data = [];
for ($i = $taps_old; $i < $taps_new; $i++) {
    $data[] = ['growlerstation_id' => $id];
}
Beertap::insert($data);

注意选择使用 insert().

时您将失去 Eloquent 功能,例如自动时间戳和模型事件

pop() 将删除您本地集合中的最后一项,但不会将该更改保存到数据库中。

假设它是一个 Beertap 对象,这样的事情应该可行:

警告:未经测试的代码

    ...
    elseif ($taps_old > $taps_new) {
        for ($i = $taps_new; $i < $taps_old; $i++) {
            $delete_me = $taps->pop();
            $delete_me->delete();
        }
    }

或更简洁:$taps->pop()->delete();