我在Laravel中创建了一个按任务计划运行的命令。
以下是命令逻辑:
public function handle()
{
$commentNotifications = CommentNotification::where('task_performed', 0)
->get();
foreach ($commentNotifications as $commentNotification) {
//blah blah
}
$commentNotifications->update(['task_performed' => 1]);
$this->comment(sprintf('Completed %d CommentNotification(s)', $commentNotifications->count()));
}
然而,这返回了以下错误:
方法Illuminate\Database\Eloquent\Collection::update不存在。
所以我尝试了这个:
$commentNotifications->task_performed = 1;
$commentNotifications->save();
但这个返回:
方法Illuminate\Database\Eloquent\Collection::save不存在。
为什么会发生这种情况?
这里有两个问题。一个是您对Eloquent集合的理解,然后您需要用一个查询更新多个记录。
首先,集合只是一组内存中的记录,您可以对其进行迭代。Eloquent集合只是它的扩展,其中这些记录是从数据库中提取的,通常有一组模型作为基础项。它还有一些额外的方法来处理这些模型。
但是,它根本没有直接绑定到数据库。这意味着像update这样的函数将不起作用,因此它们不存在。
为了更新集合中的多个记录,您不需要先将它们加载到内存中(除非您想在其他地方使用它们(。只需使用Builder创建一个查询,并对该查询调用更新
CommentNotification::where('task_performed', 0)->update(['task_performed' = 1]);
这将创建预期的SQL查询:
UPDATE comment_notifications SET task_performed = 1 WHERE task_performed = 0;
编辑-回答您关于大规模更新的问题:
如果您只需要更新记录的子集,只需在更新中添加一个额外的过滤器
CommentNotification::whereIn('id', [1, 2, 3])
->where('task_performed', 0)
->update(['task_performed' = 1]);
这将仅更新具有这些ID的记录,然后仅在未执行任务时更新。如何获取id值数组将取决于您自己。
您使用的get((返回一个集合,因此您不能使用update和save,因为它们是雄辩模型类的方法使用first((获取第一个模型而不是集合,或者使用foreach内部的update更新集合中的每个项。
save((和update((存在于Illuminate\Database\Eloquent\Model中
例如
foreach ($commentNotifications as $commentNotification) {
$commentNotification->update(['task_performed' => 1]);
}
->get()
返回一个集合。使用循环更新:
public function handle()
{
$commentNotifications = CommentNotification::where('task_performed', 0)
->get();
foreach ($commentNotifications as $commentNotification) {
$commentNotification->task_performed = 1;
$commentNotification->save();
}
$this->comment(sprintf('Completed %d CommentNotification(s)', $commentNotifications->count()));
}
或者,使用"批量更新"。
CommentNotification::where('task_performed', 0)->update(['task_performed' => 1]);