NTM Solutions

Thứ Năm, 23 tháng 7, 2026

🚀 Laravel 12 (2026) — Bài 17 — Polymorphic Relationship

Ở các bài trước, mỗi Relationship đều liên kết giữa các Model cố định.

Ví dụ:

  • User ↔ Profile

  • User ↔ Post

  • Post ↔ Tag

Tuy nhiên trong thực tế, có nhiều trường hợp nhiều Model khác nhau cùng chia sẻ một loại dữ liệu.

Ví dụ:

  • Post có Comment.

  • Video có Comment.

  • Product có Comment.

Nếu tạo riêng ba bảng bình luận thì sẽ rất khó quản lý.

Laravel giải quyết vấn đề này bằng Polymorphic Relationship.


Polymorphic Relationship là gì?

Polymorphic Relationship cho phép một bảng được dùng chung cho nhiều Model khác nhau.

Ví dụ:

Post
      │
      │
Video │──────► Comments
      │
Product

Tất cả đều dùng chung bảng comments.


Ví dụ cơ sở dữ liệu

Bảng posts

id title
1 Laravel 12

Bảng videos

id title
1 Laravel Tutorial

Bảng comments

id body commentable_id commentable_type
1 Hay quá 1 App\Models\Post
2 Rất hữu ích 1 App\Models\Video

Thay vì dùng post_id hoặc video_id, Laravel sử dụng:

  • commentable_id
  • commentable_type

để xác định Comment thuộc về Model nào.

Chuẩn bị Model Comment

Để lưu các bình luận, trước tiên chúng ta cần tạo Model Comment kèm Migration.

php artisan make:model Comment -m

Laravel sẽ tạo:

app/
└── Models/
    └── Comment.php

database/
└── migrations/
    xxxx_create_comments_table.php

tạo Video thì:

php artisan make:model Video -m

Ít nhất nên có:

Schema::create('videos', function (Blueprint $table) {
    $table->id();

    $table->string('title');

    $table->text('description')->nullable();

    $table->timestamps();
});

Trong model Video:

class Video extends Model
{
    protected $fillable = [
        'title',
        'description'
    ];

    public function comments()
    {
        return $this->morphMany(
            Comment::class,
            'commentable'
        );
    }
}

Migration

Ví dụ tạo bảng comments:

Schema::create('comments', function (Blueprint $table) {

    $table->id();

    $table->text('body');

    $table->morphs('commentable');

    $table->timestamps();

});

Lệnh:

$table->morphs('commentable');

sẽ tự tạo hai cột:

commentable_id

commentable_type

Đây là chuẩn của Laravel.


morphMany()

Trong model Post:

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

Model Video cũng tương tự:

class Video extends Model
{
    public function comments()
    {
        return $this->morphMany(
            Comment::class,
            'commentable'
        );
    }
}

Một bảng comments có thể phục vụ nhiều Model.


morphTo()

Trong model Comment:

class Comment extends Model
{
    protected $fillable = [
        'body'
    ];

    public function commentable()
    {
        return $this->morphTo();
    }
}

Laravel sẽ tự xác định Comment thuộc Post hay Video.

Tạo Comment

use App\Models\Post;
use App\Models\Comment;

Route::get('/test', function () {

$post = Post::find(1); $post->comments()->create([ 'body' => 'Bài viết rất hay!' ]);
});

Laravel sẽ tự lưu:

commentable_id = 1

commentable_type = App\Models\Post

Lấy Comment của Post

$post = Post::find(1);

foreach ($post->comments as $comment) {

    echo $comment->body;

}

Xác định Comment thuộc Model nào

$comment = Comment::find(1);

$item = $comment->commentable;

Nếu Comment thuộc Post:

echo $item->title;

Nếu thuộc Video:

echo $item->title;

Bạn không cần kiểm tra thủ công.


Một ví dụ thực tế

Ngoài Comment, Polymorphic còn được dùng cho:

Post
Video
Product
Course
        │
        ▼
     Images

Một bảng images có thể lưu hình ảnh cho nhiều Model.

Hoặc:

Post
Video
Product
        │
        ▼
      Likes

Hay:

Post
Video
Product
Course
        │
        ▼
     Attachments

Đây đều là các ứng dụng phổ biến của Polymorphic Relationship.


Ưu điểm

Polymorphic Relationship giúp:

  • Giảm số lượng bảng.

  • Tránh trùng lặp dữ liệu.

  • Dễ mở rộng hệ thống.

  • Không cần tạo nhiều bảng giống nhau.

Đây là lý do tính năng này được sử dụng trong rất nhiều hệ thống CMS và mạng xã hội.


Tổng kết

Trong bài này chúng ta đã học:

  • Polymorphic Relationship là gì.

  • morphs().

  • morphMany().

  • morphTo().

  • Chia sẻ một bảng cho nhiều Model.

  • Tạo và truy cập dữ liệu bằng Polymorphic.

Đây là Relationship nâng cao nhưng rất mạnh mẽ của Eloquent ORM, đặc biệt hữu ích trong các ứng dụng có nhiều loại đối tượng cùng sử dụng chung dữ liệu như bình luận, hình ảnh hoặc tệp đính kèm.


Bài tập

  1. Tạo model Comment.

  2. Tạo bảng comments sử dụng $table->morphs('commentable').

  3. Khai báo morphMany() trong model Post.

  4. Khai báo morphMany() trong model Video.

  5. Khai báo morphTo() trong model Comment.

  6. Tạo một Comment cho Post.

  7. Hiển thị tất cả Comment của một Video.


Kết thúc phần Relationship

Đến đây, bạn đã hoàn thành toàn bộ các Relationship quan trọng trong Eloquent ORM:

  • One To One

  • One To Many

  • Many To Many

  • Has Many Through

  • Polymorphic Relationship

Đây là nền tảng để xây dựng hầu hết các ứng dụng Laravel hiện đại như Blog, CMS, hệ thống bán hàng, LMS, ERP và REST API.


Bài tiếp theo

Bài 18, chúng ta sẽ chuyển sang Phần 5 — FORM với chủ đề Request, tìm hiểu cách Laravel tiếp nhận và xử lý dữ liệu từ biểu mẫu (Form), URL và các yêu cầu HTTP trước khi thực hiện kiểm tra dữ liệu (Validation).

x1

quay về MỤC LỤC

Không có nhận xét nào:

Đăng nhận xét

Facebook Youtube RSS