Naar de inhoud
Recognized by Laravel Match je project Contact

Gebruik Eloquent scopes en casts

Voor het laatst bijgewerkt op:

Introductie

Eloquent biedt local scopes voor herbruikbare query-constraints en attribute casts voor automatische typeconversie. Door deze functies te gebruiken houd je querylogica DRY, zorg je voor consistente datatypes en maak je code expressiever. In combinatie met helpers zoals whereBelongsTo() maken ze Eloquent-queries overzichtelijker en minder foutgevoelig.

Waarom

  • DRY queries: Local scopes halen herbruikbare query-constraints eruit, waardoor gedupliceerde where-clausules door de hele codebase worden voorkomen
  • Typeveiligheid: Attribute casts converteren databasewaarden automatisch naar de juiste PHP-types (booleans, arrays, datums, decimalen)
  • Overzichtelijkere queries: whereBelongsTo() maakt hardgecodeerde foreign key-verwijzingen overbodig, waardoor relatiequeries beter leesbaar worden
  • Betere templates: Door datumkolommen te casten kun je Carbon-methoden direct in Blade-templates gebruiken in plaats van strings handmatig te parsen

Geschikt voor

  • Elk model met herhaalde querypatronen (actieve gebruikers, gepubliceerde posts, enz.)
  • Modellen met JSON-, boolean-, decimal- of datumkolommen
  • Applicaties die Blade of API-responses gebruiken die datums formatteren

Minder geschikt voor

  • Eenmalige queries die nergens worden hergebruikt
  • Global scopes moeten spaarzaam worden gebruikt, geef voor de meeste filterbehoeften de voorkeur aan local scopes

Voorbeelden

Local scopes

// Bad: duplicated query logic
$active = User::where('verified', true)->whereNotNull('activated_at')->get();
$articles = Article::whereHas('user', function ($q) {
    $q->where('verified', true)->whereNotNull('activated_at');
})->get();

// Good: reusable local scope
public function scopeActive(Builder $query): Builder
{
    return $query->where('verified', true)->whereNotNull('activated_at');
}

$active = User::active()->get();
$articles = Article::whereHas('user', fn ($q) => $q->active())->get();

Global scopes, spaarzaam gebruiken

Global scopes passen elke query op het model stilzwijgend aan, wat debuggen bemoeilijkt. Reserveer ze voor werkelijk universele constraints zoals soft deletes of multi-tenancy. Geef voor al het andere de voorkeur aan local scopes.

Attribute casts

Gebruik de casts()-methode voor automatische typeconversie:

protected function casts(): array
{
    return [
        'is_active' => 'boolean',
        'metadata' => 'array',
        'total' => 'decimal:2',
    ];
}

Cast datumkolommen correct

// Bad: manual date parsing in templates
{{ Carbon::createFromFormat('Y-d-m H-i', $order->ordered_at)->toDateString() }}

// Good: cast in the model
protected function casts(): array
{
    return [
        'ordered_at' => 'datetime',
    ];
}

// Then use directly in Blade
{{ $order->ordered_at->toDateString() }}
{{ $order->ordered_at->format('m-d') }}

Gebruik whereBelongsTo()

// Bad: hardcoded foreign key
Post::where('user_id', $user->id)->get();

// Good: cleaner and relationship-aware
Post::whereBelongsTo($user)->get();
Post::whereBelongsTo($user, 'author')->get();

Meer info

Skill

Laravel Boost Skill

Gebruik deze skill om de richtlijn rechtstreeks toe te passen met een AI-assistent.

Use this skill when a Laravel task touches this best practice. It is self-contained so it can be installed independently by Laravel Boost or another agent-skill system.

## Core Guidance

Eloquent provides local scopes for reusable query constraints and attribute casts for automatic type conversion. Using these features keeps query logic DRY, ensures consistent data types, and makes code more expressive. Combined with helpers like `whereBelongsTo()`, they make Eloquent queries cleaner and less error-prone.

## Why It Matters

- **DRY queries**: Local scopes extract reusable query constraints, eliminating duplicated `where` clauses across the codebase
- **Type safety**: Attribute casts automatically convert database values to the correct PHP types (booleans, arrays, dates, decimals)
- **Cleaner queries**: `whereBelongsTo()` eliminates hardcoded foreign key references, making relationship queries more readable
- **Better templates**: Casting date columns means you can use Carbon methods directly in Blade templates instead of manually parsing strings

## Apply When

- Any model with repeated query patterns (active users, published posts, etc.)
- Models with JSON, boolean, decimal, or date columns
- Applications using Blade or API responses that format dates

## Be Careful When

- One-off queries that aren't reused anywhere
- Global scopes should be used sparingly, prefer local scopes for most filtering needs

## Canonical Source

- Full best practice: https://github.com/Dutch-Laravel-Foundation/best-practices/blob/main/database-and-eloquent-orm/use-eloquent-scopes-and-casts/BEST_PRACTICE.md
- Dutch translation: https://github.com/Dutch-Laravel-Foundation/best-practices/blob/main/database-and-eloquent-orm/use-eloquent-scopes-and-casts/translations/nl.md

## Workflow

1. Inspect the user's Laravel code before recommending changes.
2. Identify the narrow rule from this best practice that applies to the task.
3. Prefer Laravel's built-in conventions and documented APIs over custom abstractions.
4. Keep examples focused on this practice; reference other skills or practices when the task crosses boundaries.
5. Verify code changes with the project's available tests, linters, static analysis, or framework checks.

## Review Checklist

- The recommendation is Laravel-specific and grounded in this practice.
- Code examples use realistic Laravel file names, class names, and method names.
- The advice avoids mixing unrelated architecture, deployment, security, or testing topics.
- Related practices are mentioned when useful, but not re-explained in full.
- Dutch output, when requested, keeps framework and API names intact.