我正在尝试在更新时删除(或创建)模型关联的对象。每个酒吧都有几个水龙头。创建条形图时,将创建这些点击对象,您可以更新该数字,并根据需要创建或删除其他点击。
最初我只是想像这样使用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();
}
}
这似乎不是最简单的写法。有没有更好的写法?
顺便说一下,对于那些想知道的人,这是我在控制器中的更新功能中。
>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();
这应该有效 不幸的是,这不起作用,因为 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 功能。