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

Jar*_*rry 10 php laravel eloquent

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

在纯SQL中:

UPDATE table SET att = 'foo' WHERE id in (1,2,3)
Run Code Online (Sandbox Code Playgroud)

我有的代码:

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

取自这里

但不起作用.我越来越

Call to undefined method Illuminate\Database\Eloquent\Collection::update()
Run Code Online (Sandbox Code Playgroud)

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

Mat*_*row 23

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

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

whereIn将查询您的案例中的列id,第二个参数是您要返回的ID数组,但不会执行查询.在findMany您使用正在执行它并返回的模型的集合.

如果你需要让模型用于你可以做的其他事情$collection = $models->get();,它将返回模型的集合.

如果你不只是简单地将它写在一行上就行了;

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

我不推荐的另一个选择是使用以下内容;

$models = MyModel::findMany([1,2,3]);

$models->each(function ($item){
    $item->update(['att'=>'foo']);
});
Run Code Online (Sandbox Code Playgroud)

这将循环遍历集合中的所有项目并单独更新它们.但我推荐这种whereIn方法.

  • 添加了一个名为“toQuery()”的新 Collection 方法,当您已经拥有集合时,该方法将有所帮助,以避免必须循环遍历所有集合。https://laravel.com/docs/8.x/eloquent-collections#method-toquery (2认同)

Mar*_*cel 6

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

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

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

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

我不建议使用下一个示例,因为对于$models集合中的每个项目都会执行一个新的额外查询:

$models->each(function ($item) {
    $item->update(['att'=>'foo']);
});
Run Code Online (Sandbox Code Playgroud)

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

然而,当你想引发一些模型的事件,如最后一个例子(只在最后一)为好savingsavedupdatingupdated。其他提出的解决方案直接接触数据库,但模型没有被唤醒。