-
Notifications
You must be signed in to change notification settings - Fork 11.6k
Closed
Labels
Description
Laravel Version
12.19.3
PHP Version
8.2-fpm
Database Driver & Version
mariadb:10
Description
In Laravel 12, calling $model->getChanges() after performing an update() and a subsequent refresh() incorrectly shows old changes instead of resetting to an empty array. This results in false positives when determining if a model has dirty attributes. It affects workflows where you conditionally trigger actions like Laravel Scout's MakeSearchable job based on whether actual changes occurred.
Steps To Reproduce
Product::factory();
// 1. Change a field
$product->update(['update_time' => now()]);
dump($product->getChanges()); // Expected: ["update_time" => "..."]
// 2. Update with the same value (no actual change)
$product->update(['active' => $product->active]);
dump($product->getChanges()); // Expected: [], but returns previous changes instead
// 3. Refresh the model
$product->refresh();
dump($product->getChanges()); // Expected: [], but sometimes still returns previous changes
// 4. Update another field
$product->update(['title' => '123']);
dump($product->getChanges()); // Expected: ["title" => "123"]
Expected Behavior:
- After an update, the $model->getChanges() should reflect only the actual changed attributes.
- After a refresh(), the change tracking should reset to an empty state.
- Updating with the same attribute value should not mark the model as changed.
Actual Behavior:
- getChanges() retains previous change state even after refresh().
- Updating with the same value still fires update events and jobs like MakeSearchable, even though no data changed.
- This causes unintended job dispatching and unnecessary syncing with search engines or other services.
Impact:
- Incorrect dirty state tracking causes performance issues when Scout, observers, or similar systems react to false changes.
- This breaks a common optimization pattern where developers rely on $model->getChanges() to detect real changes before syncing with external services.