Learn how to use different types of relationships in Laravel Eloquent ORM
Basic one-to-one relationship
// app/Models/User.php
class User extends Model
{
public function profile()
{
return $this->hasOne(Profile::class);
}
}
// app/Models/Profile.php
class Profile extends Model
{
public function user()
{
return $this->belongsTo(User::class);
}
}
// Create
$user = User::create([
'name' => 'John Doe',
'email' => 'john@example.com'
]);
$user->profile()->create([
'bio' => 'Laravel Developer',
'website' => 'https://example.com'
]);
// Access
$user = User::find(1);
$bio = $user->profile->bio;
// Eager Loading
$user = User::with('profile')->find(1);
// Update
$user->profile->update([
'bio' => 'Full Stack Developer'
]);
Parent-child relationship
// app/Models/User.php
class User extends Model
{
public function posts()
{
return $this->hasMany(Post::class);
}
}
// app/Models/Post.php
class Post extends Model
{
public function user()
{
return $this->belongsTo(User::class);
}
}
// Create
$user = User::find(1);
$post = $user->posts()->create([
'title' => 'My First Post',
'content' => 'Hello World'
]);
// Query
$posts = $user->posts;
$latestPost = $user->posts()->latest()->first();
// With Conditions
$publishedPosts = $user->posts()
->where('status', 'published')
->get();
// Counting Related Models
$postCount = $user->posts()->count();
$userWithCount = User::withCount('posts')->get();
Complex relationships with pivot table
// app/Models/Post.php
class Post extends Model
{
public function tags()
{
return $this->belongsToMany(Tag::class)
->withTimestamps()
->withPivot('order');
}
}
// app/Models/Tag.php
class Tag extends Model
{
public function posts()
{
return $this->belongsToMany(Post::class)
->withTimestamps()
->withPivot('order');
}
}
Schema::create('post_tag', function (Blueprint $table) {
$table->id();
$table->foreignId('post_id')->constrained()->onDelete('cascade');
$table->foreignId('tag_id')->constrained()->onDelete('cascade');
$table->integer('order')->nullable();
$table->timestamps();
$table->unique(['post_id', 'tag_id']);
});
// Attach Tags
$post = Post::find(1);
$post->tags()->attach([
1 => ['order' => 1],
2 => ['order' => 2]
]);
// Sync Tags (Remove existing)
$post->tags()->sync([
1 => ['order' => 1],
2 => ['order' => 2]
]);
// Toggle Tags
$post->tags()->toggle([1, 2, 3]);
// Access Pivot Data
foreach ($post->tags as $tag) {
echo $tag->pivot->order;
}
// Query with Pivot
$post->tags()
->wherePivot('order', '>', 1)
->get();
Relationship through intermediate model
// app/Models/Country.php
class Country extends Model
{
public function posts()
{
return $this->hasManyThrough(
Post::class,
User::class,
'country_id', // Foreign key on users table
'user_id', // Foreign key on posts table
'id', // Local key on countries table
'id' // Local key on users table
);
}
}
// Relationship Chain:
// Country -> User -> Post
// Get all posts from a country
$country = Country::find(1);
$posts = $country->posts;
// With Constraints
$recentPosts = $country->posts()
->where('status', 'published')
->latest()
->get();
// Eager Loading
$countries = Country::with('posts')->get();
// With Nested Eager Loading
$countries = Country::with(['posts.comments'])->get();