NTM Solutions

Thứ Tư, 22 tháng 7, 2026

🚀 Laravel 12 (2026) — Bài 16 — Relationship Has Many Through

Sau khi đã học One To One, One To ManyMany To Many, chúng ta sẽ tìm hiểu thêm một kiểu Relationship đặc biệt của Eloquent là Has Many Through.

Kiểu quan hệ này cho phép truy cập các bản ghi ở bảng cuối cùng thông qua một Model trung gian mà không cần tự viết câu lệnh JOIN.


Has Many Through là gì?

Has Many Through là quan hệ một - nhiều - nhiều.

Ví dụ:

  • Một Country có nhiều User.

  • Một User có nhiều Post.

Suy ra:

  • Một Country có nhiều Post thông qua User.

Sơ đồ:

Country
   │
   └──── User
            │
            ├── Post
            ├── Post
            └── Post

Country không liên kết trực tiếp với Post.

Laravel sẽ đi qua bảng User.


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

Bảng countries

idname
1Việt Nam
2Nhật Bản

Bảng users

idnamecountry_id
1An1
2Bình1
3Ken2

Bảng posts

idtitleuser_id
1Laravel1
2PHP2
3MySQL3

Quan hệ:

Country
      ↓
    Users
      ↓
    Posts

Khai báo Relationship

Model Country:

class Country extends Model
{
    public function posts()
    {
        return $this->hasManyThrough(
            Post::class,
            User::class
        );
    }
}

Ý nghĩa:

  • Bắt đầu từ Country.

  • Đi qua User.

  • Lấy tất cả Post.


Lấy dữ liệu

$country = Country::find(1);

$posts = $country->posts;

Hoặc:

foreach ($country->posts as $post) {

    echo $post->title;

}

Laravel sẽ tự tạo các câu lệnh JOIN cần thiết.


SQL tương đương

Laravel sẽ sinh câu lệnh có ý tưởng tương tự:

SELECT posts.*

FROM posts

JOIN users
ON posts.user_id = users.id

WHERE users.country_id = 1;

Bạn không cần tự viết SQL.


eager loading

Có thể tải trước:

$countries = Country::with('posts')->get();

Sau đó:

foreach ($countries as $country) {

    echo $country->name;

    foreach ($country->posts as $post) {

        echo $post->title;

    }

}

Điều này giúp giảm số lượng truy vấn.


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

Giả sử hệ thống bán hàng:

Customer
      │
      ▼
    Order
      │
      ▼
 OrderItem

Một Customer có nhiều Order.

Một Order có nhiều OrderItem.

Ta có thể khai báo:

public function orderItems()
{
    return $this->hasManyThrough(
        OrderItem::class,
        Order::class
    );
}

Khi đó:

$customer->orderItems;

sẽ trả về toàn bộ sản phẩm mà khách hàng đã đặt.


Khi nào nên dùng?

Has Many Through phù hợp khi:

  • Muốn truy cập dữ liệu gián tiếp.

  • Không muốn tự viết JOIN.

  • Muốn giữ mã nguồn ngắn gọn và dễ đọc.

Ví dụ:

  • Country → Posts.

  • Customer → OrderItems.

  • Company → Employees thông qua Department.

  • School → Students thông qua ClassRoom.


So sánh

RelationshipVí dụ
One To OneUser → Profile
One To ManyUser → Posts
Many To ManyPost ↔ Tags
Has Many ThroughCountry → Posts → User

Tổng kết

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

  • Khái niệm Has Many Through.

  • Truy cập dữ liệu thông qua Model trung gian.

  • Khai báo hasManyThrough().

  • Lấy dữ liệu bằng Eloquent.

  • with() để tối ưu truy vấn.

Đây là một Relationship mạnh mẽ giúp giảm đáng kể số lượng câu lệnh JOIN thủ công trong các dự án lớn.


Bài tập

  1. Tạo model Country.

  2. Thêm khóa ngoại country_id vào bảng users.

  3. Khai báo hasManyThrough() trong model Country.

  4. Hiển thị tất cả Post của Country có id = 1.

  5. Sử dụng with('posts') để lấy danh sách Country cùng các Post liên quan.


Bài tiếp theo

Ở bài sau, chúng ta sẽ tìm hiểu Polymorphic Relationship, một kiểu quan hệ linh hoạt cho phép nhiều Model khác nhau cùng chia sẻ một bảng dữ liệu, chẳng hạn như PostVideo đều có thể sử dụng chung bảng comments.

x0

quay về MỤC LỤC

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

Đăng nhận xét

Facebook Youtube RSS