1️⃣ One to One (Has One)

Relasi satu ke satu berarti satu baris di satu tabel memiliki tepat satu baris terkait di tabel lain.

📌 Contoh dalam Blog:
Setiap Author memiliki satu profil (Profile).

Migration

// Author Migration
Schema::create('authors', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    $table->string('email')->unique();
    $table->timestamps();
});

// Profile Migration
Schema::create('profiles', function (Blueprint $table) {
    $table->id();
    $table->foreignId('author_id')->constrained()->onDelete('cascade');
    $table->string('bio')->nullable();
    $table->timestamps();
});

Model

class Author extends Model
{
    public function profile()
    {
        return $this->hasOne(Profile::class);
    }
}

class Profile extends Model
{
    public function author()
    {
        return $this->belongsTo(Author::class);
    }
}

Controller

$author = Author::with('profile')->find(1);
echo $author->profile->bio;

Blade View

<p>Author: {{ $author->name }}</p>
<p>Bio: {{ $author->profile->bio }}</p>

2️⃣ One to Many (Has Many)

Relasi satu ke banyak berarti satu baris di satu tabel memiliki banyak baris terkait di tabel lain.

📌 Contoh dalam Blog:
Satu Post bisa memiliki banyak komentar.

Migration

// Posts Table
Schema::create('posts', function (Blueprint $table) {
    $table->id();
    $table->string('title');
    $table->text('content');
    $table->foreignId('author_id')->constrained()->onDelete('cascade');
    $table->timestamps();
});

// Comments Table
Schema::create('comments', function (Blueprint $table) {
    $table->id();
    $table->foreignId('post_id')->constrained()->onDelete('cascade');
    $table->text('body');
    $table->timestamps();
});

Model

class Post extends Model
{
    public function comments()
    {
        return $this->hasMany(Comment::class);
    }
}

class Comment extends Model
{
    public function post()
    {
        return $this->belongsTo(Post::class);
    }
}

Controller

$post = Post::with('comments')->find(1);
foreach ($post->comments as $comment) {
    echo $comment->body;
}

Blade View

<h2>{{ $post->title }}</h2>
<p>{{ $post->content }}</p>

<h3>Comments:</h3>
@foreach ($post->comments as $comment)
    <p>{{ $comment->body }}</p>
@endforeach

3️⃣ One to Many (Inverse) / Belongs To

Relasi belongsTo adalah kebalikan dari hasMany, artinya banyak komentar dimiliki oleh satu post.

📌 Contoh dalam Blog:
Setiap Comment hanya dimiliki oleh satu Post.

Model

class Comment extends Model
{
    public function post()
    {
        return $this->belongsTo(Post::class);
    }
}

Controller

$comment = Comment::find(1);
echo $comment->post->title;

Blade View

<p>Komentar: {{ $comment->body }}</p>
<p>Pada post: {{ $comment->post->title }}</p>

4️⃣ Has One of Many

Kadang kita ingin mendapatkan satu data tertentu dari banyak data. Misalnya, post terakhir dari seorang author.

📌 Contoh dalam Blog:
Dapatkan post terbaru dari seorang Author.

Model

class Author extends Model
{
    public function latestPost()
    {
        return $this->hasOne(Post::class)->latestOfMany();
    }
}

Controller

$author = Author::with('latestPost')->find(1);
echo $author->latestPost->title;

Blade View

<h2>Post Terbaru: {{ $author->latestPost->title }}</h2>

5️⃣ Has One Through

📌 Contoh dalam Blog:
Setiap Profile dimiliki oleh Author, dan Author memiliki satu Post.

Model

class Profile extends Model
{
    public function latestPost()
    {
        return $this->hasOneThrough(Post::class, Author::class);
    }
}

Controller

$profile = Profile::with('latestPost')->find(1);
echo $profile->latestPost->title;

6️⃣ Has Many Through

Relasi ini memungkinkan kita mendapatkan banyak data terkait melalui tabel perantara.

📌 Contoh dalam Blog:
Dapatkan semua komentar dari seorang Author.

Model

class Author extends Model
{
    public function comments()
    {
        return $this->hasManyThrough(Comment::class, Post::class);
    }
}

Controller

$author = Author::with('comments')->find(1);
foreach ($author->comments as $comment) {
    echo $comment->body;
}

Blade View

<h2>Komentar dari Postingan {{ $author->name }}</h2>
@foreach ($author->comments as $comment)
    <p>{{ $comment->body }}</p>
@endforeach

Kesimpulan

Relasi Kegunaan dalam Blog
One to One Setiap Author punya Profile
One to Many Satu Post punya banyak Comments
One to Many (Inverse) Setiap Comment hanya punya satu Post
Has One of Many Dapatkan post terbaru dari seorang Author
Has One Through Dapatkan post dari profil
Has Many Through Dapatkan semua komentar dari seorang Author

💡 Tips:

  • Gunakan with('relationship') untuk eager loading agar query lebih efisien.
  • Gunakan latestOfMany() untuk mengambil data terbaru dari sekumpulan data.