<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
class Post extends Model
{
protected $fillable = ['title', 'body', 'user_id', 'published_at'];
protected $casts = [
'published_at' => 'datetime',
];
public function author(): BelongsTo
{
return $this->belongsTo(User::class, 'user_id');
}
public function comments(): HasMany
{
return $this->hasMany(Comment::class);
}
public function tags(): BelongsToMany
{
return $this->belongsToMany(Tag::class)
->withTimestamps()
->withPivot('order');
}
public function scopePublished($query)
{
return $query->whereNotNull('published_at')
->where('published_at', '<=', now());
}
}
<?php
namespace App\Http\Controllers;
use App\Models\Post;
use Illuminate\Http\Request;
class PostController extends Controller
{
public function index(Request $request)
{
// Eager load relationships to prevent N+1 queries
$posts = Post::query()
->with(['author', 'tags'])
->withCount('comments')
->when($request->has('include_comments'), function ($query) {
$query->with('comments.author');
})
->published()
->latest()
->paginate(20);
return view('posts.index', compact('posts'));
}
public function show(Post $post)
{
// Load relationships after retrieval
$post->load(['author', 'comments.author', 'tags']);
return view('posts.show', compact('post'));
}
}
Eloquent ORM makes working with database relationships intuitive and powerful. I define relationships using methods like belongsTo, hasMany, and belongsToMany that return query builders. The beauty of Eloquent is lazy loading—relationships load only when accessed. However, this causes N+1 queries in loops. The with() method eager loads relationships in a single query, dramatically improving performance. I use load() to eager load after retrieving models, and withCount() to get relationship counts without loading full models. Nested eager loading via dot notation handles deep relationships. The when() method conditionally eager loads based on request parameters. Proper eager loading is essential for performant Laravel applications.