Skip to content

[12.x] Fix $model->incrementEach() and decrementEach() to scope query to model's primary key#59065

Draft
sumaiazaman wants to merge 1 commit intolaravel:12.xfrom
sumaiazaman:fix/eloquent-increment-each-scoping
Draft

[12.x] Fix $model->incrementEach() and decrementEach() to scope query to model's primary key#59065
sumaiazaman wants to merge 1 commit intolaravel:12.xfrom
sumaiazaman:fix/eloquent-increment-each-scoping

Conversation

@sumaiazaman
Copy link
Contributor

Description

Fixes #57262

When calling $model->incrementEach() or $model->decrementEach() on an existing Eloquent model instance, the call was forwarded via __call() to the query builder without a WHERE clause scoped to the model's primary key. This caused ALL rows in the table to be updated instead of just the specific model instance — a serious data corruption bug.

// Correctly scoped to $model — only updates this record
$model->increment('number');

// BUG: updates ALL records in the table 😢
$model->incrementEach([
    'number' => 1,
    'another_number' => 1,
]);

Root Cause

increment() and decrement() are listed in __call() and dispatched to the model's own increment() and decrement() are listed in __ctoincrement()anddecrentincrement()decrementEach() were **not** in that list, so they fell thincrement()anddecrement()are listed in__call()and dispatched to the model's ownincremeusincrement() and dncrincrementanddecrementEach()protected methods onModel, mirroring the existing increment()/decrement()` pattern.

  • Added a shared incrementOrDecrementEach() helper that uses setKeysForSaveQuery() to scope the update to the model's primary key, fires updating/updated model events, and syncs the model's in-memory attributes after the update.
  • Regist- Registh - Regist- Registh - Regist- Registh - Regist- Registh - Reng forwarded to the query builder.

Tests

Added two unit tests to DatabaseEloquentModelTest:

  • - - - - - - hO- - - - - - - hO- yToModelKey -------------mentEachOnExistingModelScopesQueryToModelKey

Both verify that WHERE id = ? is applied ande model's in-memory attributes are updated correctly.

…odel key

When calling $model->incrementEach() or $model->decrementEach() on an
existing model instance, the call was forwarded via __call() to the query
builder without a WHERE clause scoped to the model's primary key. This
caused ALL rows in the table to be updated instead of just the specific
model instance — a data corruption bug.

This fix adds incrementEach() and decrementEach() methods directly on the
Model class (mirroring the existing increment()/decrement() pattern) and
registers them in __call() so they are intercepted before being forwarded
to the query builder.

The new incrementOrDecrementEach() method uses setKeysForSaveQuery() to
scope the update to the model's primary key, fires the updating/updated
model events, and syncs the model's in-memory attributes after the date.

Fixes: laravel#57262
@crynobone crynobone marked this pull request as draft March 3, 2026 11:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

$model->incrementEach() affects all models in the database table (instead of just $model)

1 participant