Eloquent-更新集合中的所有模型


Eloquent - Updating all models in a collection

我想在集合的所有模型中设置某个属性。

在纯SQL中:

UPDATE table SET att = 'foo' WHERE id in (1,2,3)

我的代码是:

$models = MyModel::findMany([1,2,3]);
$models->update(['att'=>'foo']);

从这里获取

但不起作用。我得到

Call to undefined method Illuminate'Database'Eloquent'Collection::update()

我发现的唯一方法是使用查询生成器构建查询,但我宁愿避免这种情况。

您返回的是一个集合,而不是保持查询打开以进行更新。就像你的例子一样。

$models = MyModel::whereIn('id',[1,2,3]);
$models->update(['att'=>'foo']);

whereIn将查询列。在id的情况下,第二个参数是要返回的id数组,但不会执行查询。您使用的findMany正在执行它,因此返回了一个模型集合。

如果您需要让模型用于其他用途,可以执行$collection = $models->get();,它将返回模型的集合。

如果你不只是简单地把它写在一行,就像这样;

MyModel::whereIn('id',[1,2,3])->update(['att'=>'foo']);

另一个我不建议使用的选项是:;

$models = MyModel::findMany([1,2,3]);
$models->each(function ($item){
    $item->update(['att'=>'foo']);
});

这将循环遍历集合中的所有项目,并分别更新它们。但我推荐whereIn方法。

单个查询的最佳解决方案仍然是:

MyModel::whereIn('id',[1,2,3])->update(['att'=>'foo']);

如果您已经有一个模型集合,并且想要进行直接更新,则可以使用modelKeys()方法。考虑一下,在进行此更新后,您的$models集合仍然过时,您可能需要刷新它:

MyModel::whereIn('id', $models->modelKeys())->update(['att'=>'foo']);
$models = MyModel::findMany($models->modelKeys());

我不推荐下一个例子,因为对于$models集合的每一个项目,都会执行一个新的额外查询:

$models->each(function ($item) {
    $item->update(['att'=>'foo']);
});

或者更简单,从Laravel 5.4你可以做$models->each->update(['att'=>'foo']);

但是,当您想要触发一些模型事件(如savingsavedupdatingupdated)时,最后一个示例(也是仅最后一个)是好的。其他提出的解决方案直接涉及数据库,但模型没有被唤醒。

只需使用以下内容:

MyModel::query()->update([
    "att" => "foo"
]);

请注意,批量更新模型不会触发回调updatingupdated事件。如果你需要解雇这些人,你必须单独执行每个更新,例如这样(假设$models是一个模型集合):

$models->each(fn($model) => $model->update(['att'=>'foo']) );