Go back
10 months ago

Belajar relasi "One To Many" pada Laravel

Bayangkan jika kita berbicara tentang blog post, setiap posts mempunyai seorang penulis, dan setiap penulis, pastinya mempunyai beberapa tulisan (posts).

Silahkan buat model baru dengan nama Post dan sekalian migrasinya seperti berikut.

your-project > php artisan make:model Post -m

Silahkan buka 2020_03_21_060606_create_books_table.php di (your-project/database/migrations) yang baru saja kita buat. Dan mari kita buat simpel kolom seperti berikut, yang paling penting yang Anda perhatikan pada struktur table berikut adalah field user_id yang bertipe unsigned big integer,

Schema::create('books', function (Blueprint $table) {
    $table->id();
    $table->foreign('user_id');
    $table->string('title');
    $table->text('body');
    $table->timestamps();
});

Ketika sudah, silahkan migrate dengan cara

your-project > php artisan migrate

Sekarang buka model User.php, dan silahkan buat relasi nya seperti berikut.

namespace App;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class User extends Authenticatable
{
    ...
    public function posts()
    {
        return $this->hasMany(Post::class);
    }
}

Jika dilihat, ini sangat readable (terbaca), bahwa setiap user bisa mempunyai banyak post. Dan sekarang silahkan buka Post.php model dan buat relasi untuk usernya.

namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
    public function user()
    {
        return $this->belongsTo(User::class);
    }
}

Jika anda lihat, pada relasi di atas, pastinya kita sudah tau, bawah setiap post pasti ada penulisnya. Lanjut kita akan bahas masalah parameter, pada table users, kita tadi buat relasi untuk tabel users nama fieldnya user_id, sehingga kita tidak perlu membuat parameter seperti

$this->belongsTo(User::class, 'name_of_column_id')

Tapi ketika misalnya Anda buat tadi dia menjadi id_user, maka laravel akan bingung siapa sebenarnya field relasinya, maka anda bisa kasi parameter sesuai nama kolom yang Anda buat seperti

$this->belongsTo(User::class, 'id_user')

Bagaimana cara menyimpannya ?

Ada beberapa cara untuk menyimpan post dengan penulisnya, cuma disini kita akan bahas 1 saja.

Pastinya untuk melakukan ini, Anda pasti sudah mempunya setup form dan authenticated user (yang sudah login).

Kita tidak akan cover semuanya, cuma kita akan belajar caranya tepat pada controllernya.

Sebelum kita nantinya mendapat error tentang Mass Assignment, Silahkan buka model Post.php dan setup guarded ke array kosong seperti berikut.

class Post extends Model
{
    protected $guarded = [];
    ...

Setelah selesai, nantinya Anda akan akan menyimpan post nya dari relasi yang kita buat di model User.php. Open controllernya dan buat di method post anda.

public function store()
{
    auth()->user()->posts()->create([
        'column' => request('column'),
    ]);
    return back();
}

Itu cara menyimpan, bagaimana cara menampilkannya dari controller ke viewnya.

pada method yang Anda buat pastinya bertipe get, seperti berikut.

public function index()
{
    $posts = Post::get();
    return view('posts.index', compact('posts'));
}

Dan pada blade filenya, bisa anda loop variabel posts yang dari kontorller seperti berikut.

@extends('layouts.app')
@section('content')
    @foreach ($posts as $post)
        <div>
            {{ $post->title }} by {{ $post->user->name }}
        </div>
    @endforeach
@endsection

Tapi ingat, jika Anda masukkan user di setiap post yang Anda, query akan berulang terus yang mana itu disebut dengan N+1 Problem, nah disini kita butuh yang namanya eager-loader, tambahkan with builder sewaktu kita fetching data seperti berikut.

$posts = Post::with('user')->get();

And we're done. That's it.