laravel-eloquent
Develops Eloquent models, relationships, scopes, and query optimization. Activates when creating models, defining relationships (hasMany, belongsTo, morphTo), writing scopes, eager loading, query buil
Files1
View on GitHubSKILL.md.claude/skills/laravel-eloquent
GitHubLaravel Eloquent Development
When to Apply
Activate this skill when:
- Creating or modifying Eloquent models
- Defining model relationships
- Writing query scopes (local or global)
- Optimizing queries or fixing N+1 problems
- Working with accessors, mutators, or casts
- Implementing model events or observers
Documentation
Use search-docs for detailed Eloquent patterns and documentation.
Basic Usage
Creating Models
Use Artisan to create models with related files:
php artisan make:model Post --migration --factory --seeder
Relationships
Always use explicit return types on relationship methods:
<code-snippet name="Eloquent Relationships" lang="php"> use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\BelongsTo;public function posts(): HasMany { return $this->hasMany(Post::class); }
public function author(): BelongsTo { return $this->belongsTo(User::class, 'author_id'); } </code-snippet>
Eager Loading
Prevent N+1 queries by eager loading relationships:
<code-snippet name="Eager Loading" lang="php"> // Good - eager loads in 2 queries $posts = Post::with(['author', 'comments'])->get();// Bad - causes N+1 queries $posts = Post::all(); foreach ($posts as $post) { echo $post->author->name; // Query per post } </code-snippet>
Constraining Eager Loads
<code-snippet name="Constrained Eager Loading" lang="php"> $users = User::with(['posts' => function ($query) { $query->where('published', true) ->latest() ->limit(10); }])->get(); </code-snippet>Local Scopes
<code-snippet name="Local Scopes" lang="php"> use Illuminate\Database\Eloquent\Builder;public function scopePublished(Builder $query): Builder { return $query->where('published_at', '<=', now()); }
public function scopeByAuthor(Builder $query, User $author): Builder { return $query->where('author_id', $author->id); }
// Usage Post::published()->byAuthor($user)->get(); </code-snippet>
Casts
Define casts in the casts() method (Laravel 11+):
Accessors and Mutators
Use attribute casting for simple transformations:
<code-snippet name="Accessors and Mutators" lang="php"> use Illuminate\Database\Eloquent\Casts\Attribute;protected function fullName(): Attribute { return Attribute::make( get: fn () => "{$this->first_name} {$this->last_name}", ); }
protected function email(): Attribute { return Attribute::make( set: fn (string $value) => strtolower($value), ); } </code-snippet>
Query Building
Prefer Model::query() over DB:: facade:
// Avoid $posts = DB::table('posts')->where(...)->get(); </code-snippet>
Model Events and Observers
<code-snippet name="Model Observer" lang="php"> // app/Observers/PostObserver.php class PostObserver { public function creating(Post $post): void { $post->slug = Str::slug($post->title); }public function deleted(Post $post): void
{
Storage::delete($post->featured_image);
}
} </code-snippet>
Common Pitfalls
- Not using eager loading, causing N+1 queries
- Using
DB::instead of Eloquent models - Missing return types on relationship methods
- Forgetting to create factories and seeders with new models
- Using
$castsproperty instead ofcasts()method in Laravel 11+ - Not constraining eager loads when only subset of data is needed