How to Use Local Scope in Eloquent for Cleaner Queries
In Laravel Eloquent, you create a
local scope by adding a method starting with scope in your model. You call it on the model query without the scope prefix to reuse query logic simply and clearly.Syntax
A local scope method in an Eloquent model starts with the prefix scope followed by a descriptive name. It always receives a $query parameter and optionally other parameters for filtering.
Example parts:
scopeActive($query): defines a scope namedactive.$query->where('status', 'active'): modifies the query.- Call it as
Model::active()->get()without thescopeprefix.
php
public function scopeActive($query) { return $query->where('status', 'active'); }
Example
This example shows a Post model with a local scope published that filters posts with published_at date in the past. You can call Post::published()->get() to get only published posts.
php
<?php namespace App\Models; use Illuminate\Database\Eloquent\Model; use Carbon\Carbon; class Post extends Model { public function scopePublished($query) { return $query->where('published_at', '<=', Carbon::now()); } } // Usage example: $publishedPosts = Post::published()->get(); foreach ($publishedPosts as $post) { echo $post->title . "\n"; }
Output
Title of published post 1
Title of published post 2
...
Common Pitfalls
Common mistakes when using local scopes include:
- Calling the scope method with the
scopeprefix (wrong:Post::scopePublished()). - Not returning the query builder from the scope method.
- Defining the scope method as static (it should be an instance method).
Correct usage always calls the scope without scope and returns the query.
php
/* Wrong way: */ public static function scopePublished($query) { $query->where('published_at', '<=', now()); } // Called as Post::scopePublished()->get(); // This will fail /* Right way: */ public function scopePublished($query) { return $query->where('published_at', '<=', now()); } // Called as Post::published()->get();
Quick Reference
- Define local scope methods in your Eloquent model with
scopeName($query, ...). - Call scopes without the
scopeprefix:Model::name()->get(). - Always return the query builder from the scope method.
- Use scopes to keep queries reusable and clean.
Key Takeaways
Local scopes start with 'scope' in the model but are called without it.
Always return the query builder from your scope method.
Use local scopes to reuse query logic and keep code clean.
Do not define scope methods as static.
Call scopes as chainable methods on the model query.