Sau khi đã biết cách truy vấn dữ liệu bằng Eloquent và Query Builder, bước tiếp theo là tìm hiểu Relationship (mối quan hệ) giữa các Model.
Trong thực tế, dữ liệu hiếm khi tồn tại độc lập.
Một người dùng có thể có hồ sơ cá nhân, một bài viết thuộc về một danh mục, một sản phẩm có nhiều hình ảnh...
Việc liên kết các bảng với nhau giúp cơ sở dữ liệu trở nên khoa học và tránh trùng lặp dữ liệu.
Trong bài này, chúng ta sẽ tìm hiểu mối quan hệ đơn giản nhất: One To One.
Relationship là gì?
Relationship là cách Laravel mô tả mối quan hệ giữa các Model.
Ví dụ:
Một User có một Profile.
Một Passport thuộc về một Person.
Một Student có một Student Card.
Đây đều là các mối quan hệ một - một (One To One).
Ví dụ cơ sở dữ liệu
Ta có hai bảng:
users
| id | name |
|---|---|
| 1 | Nguyễn Văn A |
| 2 | Trần Văn B |
profiles
| id | user_id | phone | address |
|---|---|---|---|
| 1 | 1 | 0901234567 | Hà Nội |
| 2 | 2 | 0912345678 | Đà Nẵng |
Mỗi User chỉ có một Profile và mỗi Profile chỉ thuộc về một User.
Tạo Migration
Tạo bảng Profile:
php artisan make:migration create_profiles_table
Migration:
Schema::create('profiles', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')
->constrained()
->cascadeOnDelete();
$table->string('phone');
$table->string('address');
$table->timestamps();
});
Sau đó chạy:
php artisan migrate
Tạo Model
php artisan make:model Profile
Laravel sẽ tạo:
app/
└── Models/
├── User.php
└── Profile.php
hasOne()
Trong model User:
class User extends Authenticatable
{
public function profile()
{
return $this->hasOne(Profile::class);
}
}
Ý nghĩa:
Một User có một Profile.
Laravel sẽ mặc định tìm khóa ngoại user_id.
belongsTo()
Trong model Profile:
class Profile extends Model
{
public function user()
{
return $this->belongsTo(User::class);
}
}
Ý nghĩa:
Profile thuộc về một User.
Lấy dữ liệu
Lấy Profile của User:
$user = User::find(1);
echo $user->profile->phone;
Hoặc:
echo $user->profile->address;
Laravel sẽ tự động truy vấn bảng profiles.
Lấy User từ Profile
Ngược lại:
$profile = Profile::find(1);
echo $profile->user->name;
Laravel sẽ truy vấn bảng users.
Tạo dữ liệu liên kết
Có thể tạo Profile thông qua User.
$user = User::find(1);
$user->profile()->create([
'phone' => '0901234567',
'address' => 'Hồ Chí Minh'
]);
Laravel sẽ tự động gán:
user_id = 1
Bạn không cần tự điền khóa ngoại.
eager loading
Nếu hiển thị danh sách nhiều User kèm Profile, không nên để Laravel truy vấn từng Profile riêng lẻ.
Sử dụng:
$users = User::with('profile')->get();
Laravel sẽ lấy toàn bộ dữ liệu chỉ với số lượng truy vấn tối thiểu, giúp ứng dụng hoạt động nhanh hơn.
Truy cập an toàn
Không phải User nào cũng đã có Profile.
Ví dụ:
echo $user->profile->phone;
Nếu Profile chưa tồn tại sẽ phát sinh lỗi.
Có thể dùng toán tử null-safe của PHP:
echo $user->profile?->phone;
Hoặc:
optional($user->profile)->phone;
Tổng kết
Trong bài này chúng ta đã học:
Relationship là gì.
Quan hệ One To One.
hasOne().belongsTo().Truy cập dữ liệu qua Relationship.
Tạo dữ liệu liên kết.
with()để tối ưu truy vấn.Truy cập an toàn khi quan hệ chưa tồn tại.
One To One là nền tảng để hiểu các mối quan hệ phức tạp hơn trong Eloquent ORM.
Bài tập
Tạo bảng
profilescó các trườngphonevàaddress.Khai báo quan hệ
hasOne()trong modelUser.Khai báo quan hệ
belongsTo()trong modelProfile.Hiển thị số điện thoại của User có
id = 1.Hiển thị tên User từ một Profile.
Sử dụng
with('profile')để lấy danh sách User cùng thông tin Profile.
Bài tiếp theo
Ở bài tiếp theo, chúng ta sẽ tìm hiểu One To Many, mối quan hệ phổ biến nhất trong Laravel, chẳng hạn như một User có nhiều Post hoặc một Category có nhiều Post.
Đây là bài mở đầu phần Relationship, nên chỉ giới thiệu những khái niệm cốt lõi và các phương thức hasOne() và belongsTo().
Các nội dung như khóa ngoại tùy chỉnh, eager loading nâng cao hay polymorphic sẽ được trình bày ở các bài sau khi người học đã nắm vững nền tảng.
x0




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