Laravel model: fresh() vs refresh()
Published on
Laravel models have two methods for reloading the latest database values: fresh() and refresh().
They're often necessary in unit tests to assert the changes a controller made to the model.
TLDR: fresh() vs refresh()
Calling $freshModel = $model->fresh():
-
Fetches a new instance from the DB, leaving
$modelunchanged -
Won't reload relationships unless explicitly passed in via
->fresh(with: ...) -
Always uses
SELECT *, ignoring previously selected columns
Calling $model->refresh():
-
Reloads the same
$modelinstance and hands it back - Reloads all previously loaded relationships
-
Always uses
SELECT *, ignoring previously selected columns
When performance matters, use neither
In performance-critical code, use neither fresh() nor refresh().
They have the same performance problems as serializing models in queued jobs.
For example:
$user = User::query()
// Only select specific columns from the User model
->select('id', 'email', 'name')
// Load the "posts" relation, but only specific columns
->with('posts:id,title')
// Load the "activities" relation, but only the latest 5
->with(['activities' => fn (Builder $query) => $query->latest()->take(5)])
->firstWhere('email', 'user@example.com');
// Both `fresh()` and `refresh()` will:
// - "SELECT *" every User column, ignoring the subset we picked
// - Reload posts and activities, ignoring the constraints we set
$freshUser = $user->fresh(with: ['posts', 'activities']);
$user->refresh();
To refresh a model efficiently, requery it manually:
$freshUser = User::select('id', 'email', 'name')->find($user->id);