Eloquent New Model Query: Fresh Builder
Eloquent New Model Query: Fresh Builder
Eloquent New Model Query: Fresh Builder
Tip: newQuery() for Fresh Builder
$query = (new Post)->newQuery();
Starts a clean query builder without global scopes applied.
Gotcha: newQuery() Includes Global Scopes
Global scopes are still applied. Use newQueryWithoutScopes() to bypass all scopes.
Tip: resolveRouteBinding()
public function resolveRouteBinding($value, $field = null): ?Model
{
return $this->where($field ?? 'id', $value)->first();
}
Customize how route model binding resolves the model.
Gotcha: Static Methods Share State
Post::where('published', true);
Post::where('active', true); // Still includes published filter!
Always start with a fresh call: Post::query()->where(...).
Tip: newModelQuery() vs newQuery()
newModelQuery() returns a builder for the model class. newQuery() includes the model's current state.
Gotcha: Query Builder Immutability
Query builders are NOT immutable. Calling where() modifies the builder in place.
Tip: Use cursor() for Memory-Neutral Iteration
When exporting 100K rows, get() loads everything into memory. cursor() uses yield and keeps memory flat regardless of row count. Perfect for artisan commands.
Tip: whereHas() vs load() — Two Different Things
whereHas() filters the parent query by relationship existence. load() eager-loads relationships AFTER the query. Mixing them up is a common source of logic bugs.
Gotcha: withCount() Adds a Subquery
withCount('comments') runs a correlated subquery on every row. On large tables, this can be slower than a separate query. Profile before relying on it.
Senior Insight
Getting a fresh query builder instance from a model via newQuery() or on() is a pattern I use for cross-database operations. But there's a subtle issue: newQuery() inherits global scopes, which can produce unexpected results when you're querying against a different database connection. I use withoutGlobalScopes() explicitly when I need an unmodified query, and I always test cross-database queries with the actual database connection, not SQLite.
Source: Laravel Docs (https://laravel.com/docs/eloquent), Laravel News (https://laravel-news.com/), Freek.dev (https://freek.dev/tags/eloquent)