我想在集合的所有模型中设置某个属性。
在纯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']);
但是,当您想要触发一些模型事件(如saving
、saved
、updating
、updated
)时,最后一个示例(也是仅最后一个)是好的。其他提出的解决方案直接涉及数据库,但模型没有被唤醒。
只需使用以下内容:
MyModel::query()->update([
"att" => "foo"
]);
请注意,批量更新模型不会触发回调updating
和updated
事件。如果你需要解雇这些人,你必须单独执行每个更新,例如这样(假设$models
是一个模型集合):
$models->each(fn($model) => $model->update(['att'=>'foo']) );