5

When I usually update a record, I do

$myObject->update(['field' => 'value']);

And that updates both the database and my instance $myObject. However, sometimes, I need to do bulk updates, so I use the model facade and do

$result = MyObject::where(...)->update(['field' => 'value');

The issue here is that $result sends me back a boolean instead of the updated instances so what I usually have to do separately is right after I need to do the same filter, but this time a get().

$objects = MyObject::where(...)->get();

Is there a more efficient way to update and get the records in one call/request to the database?

Abdulla Nilam
  • 36,589
  • 17
  • 64
  • 85
user391986
  • 29,536
  • 39
  • 126
  • 205

5 Answers5

9

This will solve the problem

$product = Product::where('id','76887')->first();

$result = $product->update(['field' => 'value');

$theUpdatedData = $product->refresh(); 

return $theUpdatedData //This return the updated record 
Godstime John
  • 253
  • 3
  • 8
3

IMHO your way is arguably the most efficient with Eloquent.

If you care about performance more than using Eloquent then with raw queries in PostgreSQL (with RETURNING clause) or SQL Server (with OUTPUT clause) you can return updated records in one go.

MySQL unfortunately doesn't have such support on a statement level.

In all supported by Laravel databases you can also achieve this (one trip to the database) also with a stored procedure.

peterm
  • 91,357
  • 15
  • 148
  • 157
1

The easiest way to archive is.

$object = Model::find(1);

$object->field_name_to_update = 'new_value';
$object->another_field_name_to_update = 'new_value2';

$object->save();

echo $object->field_name_to_update; # has updated value
echo $object->another_field_name_to_update; # has updated value

Make sure fields are in $fillable in the model to avoid Mass Assignment error

Abdulla Nilam
  • 36,589
  • 17
  • 64
  • 85
0

you can use inside query

like this:

$messages = MessageGroup::where(function(Builder $query) use($request,$checkCountUser)
           {
            $query->whereRaw('((message_group_from_id="'.$request->student_id.'" 
            AND message_from_type = "students" 
            AND  message_group_to_id IN('.implode(',',$checkCountUser).') 
            AND message_to_type = "users") OR (message_group_to_id="'.$request->student_id.'" 
            AND message_to_type = "students" 
            AND  message_group_from_id IN('.implode(',',$checkCountUser).') 
            AND message_from_type = "users"))')->update(['message_is_read' => 1,'message_is_delivered' => 1]);
           //$query;
            return $query;
        })->get();

if you see this

kadamb
  • 1,532
  • 3
  • 29
  • 55
-1

If you want the most efficient method possible, you can update the database with the single update command, and then loop through your $objects in memory with a foreach loop and set each $object->field = 'value'. It isn't especially elegant, but that would be the most efficient way to do it in terms of speed since that way you don't need to re-fetch the models from the database.

$result = MyObject::where(...)->update(['field' => 'value');

foreach ($objects as $object) {
   $object->field = 'value';
}
orrd
  • 9,469
  • 5
  • 39
  • 31