Laravel Eloquent Relationships
Laravel Eloquent relationships describe how your tables connect, such as a user having many posts or a post having many tags. You define them as methods on models and then navigate related data like ordinary properties.
One to Many: hasMany and belongsTo
Laravel assumes posts has a user_id column. Accessing $user->posts as a property runs the query and returns a collection.
<?php
class User extends Authenticatable
{
public function posts(): HasMany
{
return $this->hasMany(Post::class);
}
}
class Post extends Model
{
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
}
$user = User::find(1);
echo $user->posts->count(), "\n";
echo Post::find(3)->user->name;3 Naeem
One to One: hasOne
<?php
public function profile(): HasOne
{
return $this->hasOne(Profile::class);
}
echo $user->profile?->city ?? 'No profile';Karachi
Many to Many: belongsToMany
A post can have many tags and a tag many posts. This needs a pivot table named post_tag with post_id and tag_id.
<?php
class Post extends Model
{
public function tags(): BelongsToMany
{
return $this->belongsToMany(Tag::class)->withTimestamps();
}
}
$post->tags()->attach([1, 2]);
$post->tags()->sync([2, 3]); // keep only 2 and 3
echo $post->tags->pluck('name')->join(', ');php, laravel
Creating Related Records
Creating through the relationship fills the foreign key automatically.
<?php
$post = $user->posts()->create([
'title' => 'My second post',
'slug' => 'my-second-post',
'body' => '...',
]);
echo $post->user_id;1
Eager Loading and the N+1 Problem
Looping over posts and reading $post->user runs one extra query per post (N+1 queries). Eager load with with() to fetch everything in two queries. withCount adds counts without loading rows.
<?php
// Bad: 1 + N queries
foreach (Post::all() as $post) { echo $post->user->name; }
// Good: 2 queries
$posts = Post::with(['user', 'tags'])->withCount('comments')->latest()->get();
foreach ($posts as $post) {
echo "{$post->title} by {$post->user->name} ({$post->comments_count} comments)\n";
}Blade tips by Naeem (4 comments) Eloquent basics by Sara (1 comments)
Querying by Relationship
<?php
$active = User::has('posts', '>=', 3)->get();
$laravelPosts = Post::whereHas('tags', fn ($q) => $q->where('name', 'laravel'))->get();
echo $active->count(), " ", $laravelPosts->count();2 7
Frequently asked questions
What is the N+1 query problem in Laravel?
It happens when you load a list and then lazily load a relationship for each item, causing one query per row. Fix it with eager loading: Model::with("relation").
What is a pivot table in Laravel?
The join table for a many-to-many relationship, named with both singular model names in alphabetical order, such as post_tag.
What is the difference between attach and sync?
attach adds new pivot rows; sync makes the pivot match exactly the IDs you pass, removing any others.