PHP
Encapsulate Reusable Query Logic with Laravel Eloquent Local Scopes
Streamline your Laravel Eloquent queries by using local scopes. This snippet shows how to define and use reusable query constraints for cleaner, more maintainable code.
// In your App\Models\Post model:
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
class Post extends Model
{
/**
* Scope a query to only include published posts.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @return \Illuminate\Database\Eloquent\Builder
*/
public function scopePublished(Builder $query): Builder
{
return $query->where('is_published', true);
}
/**
* Scope a query to only include posts from a given user.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @param int $userId
* @return \Illuminate\Database\Eloquent\Builder
*/
public function scopeByUser(Builder $query, int $userId): Builder
{
return $query->where('user_id', $userId);
}
}
// Usage in a controller or elsewhere:
use App\Models\Post;
use App\Models\User;
// Get all published posts
$publishedPosts = Post::published()->get();
// Get all published posts by a specific user (e.g., user with ID 1)
$user = User::find(1);
if ($user) {
$userPublishedPosts = Post::published()->byUser($user->id)->get();
}
// Chaining scopes
$recentPublishedPosts = Post::published()->latest()->take(5)->get();
How it works: Local scopes provide a convenient way to encapsulate reusable query logic within your Eloquent models. By defining methods prefixed with `scope` (e.g., `scopePublished`), you can easily apply common query constraints like `published()` or `byUser($userId)` to your model queries, making them more readable, maintainable, and adhering to the DRY principle. They can also be chained together.