Eloquent Model Mass Update

Eloquent model mass update

For mass update/insert features, it was requested but Taylor Otwell (Laravel author) suggest that users should use Query Builder instead. https://github.com/laravel/framework/issues/1295

Your models should generally extend Illuminate\Database\Eloquent\Model. Then you access the entity iself, for example if you have this:

<?php
Use Illuminate\Database\Eloquent\Model;

class User extends Model {

// table name defaults to "users" anyway, so this definition is only for
// demonstration on how you can set a custom one
protected $table = 'users';
// ... code omited ...

Update #2

You have to resort to query builder. To cover table naming issue, you could get it dynamically via getTable() method. The only limitation of this is that you need your user class initialized before you can use this function. Your query would be as follows:

$userTable = (new User())->getTable();
DB::table($userTable)->where('age', '<', 18)->update(array('under_18' => 1));

This way your table name is controller in User model (as shown in the example above).

Update #1

Other way to do this (not efficient in your situation) would be:

$users = User::where('age', '<', 18)->get();
foreach ($users as $user) {
$user->field = value;
$user->save();
}

This way the table name is kept in users class and your developers don't have to worry about it.

How do I mass update an Eloquent model without a where condition?

This can be done using by running

App\Flight::query()->update(['delayed' => 1]);

The query() method creates a new query builder instance, but without any initial clauses (like where conditions). Additional operations like update() can be chained after it.

Laravel Eloquent - bulk update with whereIn array

Here is a good way to solve it:
in the beginning, I used this library: https://github.com/mavinoo/laravelBatch
to update many dynamic rows, but it was really slow, then thanks to Yasin, I moved to: https://github.com/iksaku/laravel-mass-update and now it works way better.

the implementation is simple, add a simple code to the Model class, then add:

User::massUpdate(
values: [
['username' => 'iksaku', 'name' => 'Jorge González'],
['username' => 'gm_mtz', 'name' => 'Gladys Martínez'],
],
uniqueBy: 'username'
);

while uniqueBy is the key for the row, and add other columns values to change them dynamically.

How to mass update in Eloquent given an array of keys and values efficiently

Eloquent is very powerfull to manage complicated relationship, joins, eager loaded models etc... But this abstraction has a performance cost. Each model have to be created, filled and saved, it is packed with tons of features you don't need for this precise use case.

When editing thousand or even millions of records, it is highly inefficient to use Eloquent models. Instead you can either use the laravel Query builder or a raw SQL statement.

I would recommend this approach:

$table = Db::table('orders');
foreach ($xml as $row) {
$table->where('reference_key', $reference_key)
->update('new_value', (float)$row->new_value);
}

But you can also do something like this:

foreach ($xml as $row) {
DB::statement('UPDATE orders SET new_value=? WHERE reference_key=?',
[(float)$row->new_value, $reference_key]);
}

It will cut down your execution time significantly but the loop over millions of XML lines will still take a long time.

How to Mass Update(Edit) in Laravel Query Builder?

I do not see any error in your update statement so it should update all the records provided by the query (mass updates are documented here).

I guess the error is before, when you set $this->selectedStudents. Are you sure that this variable contains a simple array (not an associative array) with all the selected IDs?

You should do the following:

  • Debug the $this->selectedStudents variable to ensure its content is correct
  • Temporarily replace it by a hardcoded value [1, 2, 3] to ensure that the rest of your code is appropriately working

UPDATE

To convert $this->selectedStudents in the right format, you can do the following:

$selectedIds = [];
foreach ($this->selectedStudents as $id => $isSelected){
if ($isSelected) {
$selectedIds[] = $id;
}
}
DB::table('class_list')
->whereIn('id', $selectedIds)
->update(['section' => $this->selectedSched]);


Related Topics



Leave a reply



Submit