欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

Eloquent - Updating all models in a collection

I want to set a certain attribute in all the models of a collection.

in plain SQL:

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

the code i have:

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

taken from here

but doesn't work. I'm getting

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

the only way i have found it's building a query with the query builder but i'd rather avoid that.
 

   
Eloquent is a query builder, not an ORM. It does not define update on model instances. You can define it yourself, but in the end somewhere in your code you have to write MyModel::whereIn('id', [1, 2, 3])->update(...). – Sergiu Paraschiv Feb 5 '15 at 17:10
1 
@SergiuParaschiv Actually Eloquent is an ORM – lukasgeiter Feb 5 '15 at 17:24
   
Just googled the same question. Hai~ – JSelser Oct 7 '15 at 16:34
                                                                                               
 

正确答案  
You are returning a collection, not keeping the query open to update. Like your example is doing.

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

whereIn will query a column in your case id, the second parameter is an array of the ids you want to return, but will not execute the query. The findMany you were using was executing it thus returning a Collection of models.

If you need to get the model to use for something else you can do $collection = $models->get();and it will return a collection of the models.

If you do not just simply write it on one line like so;

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

Another option which i do not recommend is using the following;

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

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

This will loop over all the items in the collection and update them individually. But I recommend the whereIn method.

shareimprove this answer
 
   
the whereIn method worked. but what if i have a model collection. there's no way to update all of them at once? – Jarry Feb 5 '15 at 17:26
   
No there is not without going through them each i added that as an option at the end of the answer, but i do not recommend this. – Matt Burrow Feb 5 '15 at 17:27
   
no, i dont recommend it either, that's why i was looking for an alternative – Jarry Feb 5 '15 at 17:29

The best solution in one single query is still:

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

If you already have a collection of models and you want to do a direct update you can use modelKeys() method. Consider that after making this update your $models collection remains outdated and you may need to refresh it:

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

The next example I will not recommend because for every item of your $models collection a new extra query is performed:

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

or simpler, from Laravel 5.4 you can do $models->each->update(['att'=>'foo']);

However, the last example (and only the last) is good when you want to trigger some model events like savingsavedupdatingupdated. Other presented solutions are touching direct the database but models are not waked up.

shareimprove this answer
 

来自  https://stackoverflow.com/questions/28349929/eloquent-updating-all-models-in-a-collection


普通分类: