Hướng dẫn Model_Laravel - Lavarel
Lavarel

Hướng dẫn Model_Laravel - Lavarel

Author

Admin System

@root

Ngày xuất bản

18 Mar, 2026

Lượt xem

1 Lượt

Model_Laravel

Chào mừng các bạn đến với buổi học hôm nay!

Hôm nay, chúng ta sẽ "giải phẫu" một trong những trái tim của Laravel, một khái niệm mà nếu bạn nắm vững, việc tương tác với database sẽ trở nên dễ dàng, thanh lịch và mạnh mẽ hơn bao giờ hết. Đó chính là Model trong Laravel.

Model trong Laravel: Khi Dữ Liệu Biến Thành Đối Tượng Biết Nói

Bạn cứ hình dung thế này: database của chúng ta là một kho tàng khổng lồ chứa đầy những "viên ngọc" dữ liệu. Mỗi viên ngọc là một thông tin quý giá về người dùng, bài viết, sản phẩm, hay bất cứ thứ gì bạn đang quản lý. Tuy nhiên, những viên ngọc này nằm im lìm, vô tri vô giác trong các "hầm chứa" (các bảng).

Model trong Laravel, hay cụ thể hơn là Eloquent ORM (Object-Relational Mapping), chính là những "người đại diện" thông minh, những "phiên dịch viên" tài ba. Mỗi khi bạn có một "hầm chứa" dữ liệu (một bảng trong database), bạn sẽ có một Model tương ứng. Model này sẽ biến những hàng dữ liệu vô tri vô giác thành những đối tượng PHP có "linh hồn", biết nói, biết hành động.

Model Là Gì? Tại Sao Chúng Ta Cần Đến 'Đại Sứ' Này?

  1. Lớp Trừu Tượng (Abstraction Layer): Thay vì phải viết những câu lệnh SQL dài dòng, phức tạp (kiểu như SELECT * FROM users WHERE id = 1), Model cho phép bạn tương tác với database thông qua các đối tượng PHP quen thuộc. Bạn chỉ cần gọi User::find(1) là xong. Cứ như bạn đang nói chuyện với "người đại diện" của dữ liệu, chứ không phải mò mẫm trong kho bạc vậy.
  2. Ánh Xạ Đối Tượng Quan Hệ (ORM - Object-Relational Mapping): Đây là "phép thuật" chính của Model. Nó tự động ánh xạ các hàng (rows) trong bảng database thành các đối tượng (objects) PHP và ngược lại. Mỗi dòng dữ liệu trong bảng users sẽ trở thành một đối tượng User với các thuộc tính như id, name, email.
  3. Nơi Định Nghĩa Logic Dữ Liệu (Business Logic): Model không chỉ là cầu nối đơn thuần. Đây còn là nơi bạn định nghĩa các mối quan hệ giữa các bảng (một người dùng có nhiều bài viết, một bài viết thuộc về một người dùng), các phương thức truy vấn tùy chỉnh, các thuộc tính ảo (accessors/mutators), và thậm chí cả các quy tắc nghiệp vụ liên quan trực tiếp đến dữ liệu. Nó giúp giữ cho Controller của bạn "gọn gàng" hơn, chỉ tập trung vào việc điều phối.
  4. Bảo Toàn Dữ Liệu (Data Integrity): Với các tính năng như Mass Assignment Protection (bảo vệ gán dữ liệu hàng loạt) và các sự kiện (events), Model giúp bạn kiểm soát và đảm bảo dữ liệu luôn được lưu trữ một cách an toàn, đúng đắn.

Tóm lại, Model là "bộ não" của phần dữ liệu trong ứng dụng Laravel của bạn, giúp bạn thao tác với database một cách hiệu quả, an toàn và "nghệ thuật" hơn rất nhiều.


Illustration

Code Ví Dụ: Biến Ý Tưởng Thành Hiện Thực Với Các 'Sứ Giả' Dữ Liệu

Hãy cùng xây dựng một hệ thống blog đơn giản để thấy Model hoạt động như thế nào nhé!

Tạo Model: Bước Đầu Tiên Của Sự Sáng Tạo

Bạn có bảng usersposts trong database. Để tạo Model tương ứng, chúng ta dùng Artisan CLI:

php artisan make:model User
php artisan make:model Post

Laravel sẽ tạo ra hai file app/Models/User.phpapp/Models/Post.php.

app/Models/User.php (ví dụ đơn giản)

<?php

namespace App\Models;

use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;

class User extends Authenticatable
{
    use HasApiTokens, HasFactory, Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array<int, string>
     */
    protected $fillable = [
        'name',
        'email',
        'password',
    ];

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var array<int, string>
     */
    protected $hidden = [
        'password',
        'remember_token',
    ];

    /**
     * The attributes that should be cast.
     *
     * @var array<string, string>
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];

    // Định nghĩa mối quan hệ tại đây
    public function posts()
    {
        return $this->hasMany(Post::class);
    }
}

app/Models/Post.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    use HasFactory;

    // Các trường được phép gán giá trị hàng loạt
    protected $fillable = [
        'user_id',
        'title',
        'content',
        'published_at',
    ];

    // Định nghĩa mối quan hệ tại đây
    public function user()
    {
        return $this->belongsTo(User::class);
    }

    // Một accessor ví dụ
    public function getShortContentAttribute()
    {
        return substr($this->content, 0, 100) . '...';
    }
}

CRUD: 4 Phép Thuật Cơ Bản Của Dữ Liệu

Đây là cách bạn "ra lệnh" cho các "sứ giả" dữ liệu của mình:

  1. Create (Tạo mới):

    use App\Models\User;
    use App\Models\Post;
    
    // Tạo một người dùng mới
    $user = User::create([
        'name' => 'John Doe',
        'email' => 'john@example.com',
        'password' => bcrypt('secret'), // Luôn hash mật khẩu!
    ]);
    
    // Tạo một bài viết mới cho người dùng này
    $post = Post::create([
        'user_id' => $user->id,
        'title' => 'Bài viết đầu tiên của tôi',
        'content' => 'Đây là nội dung rất hay và ý nghĩa của bài viết đầu tiên.',
        'published_at' => now(),
    ]);
    
    // Hoặc cách khác, thông qua mối quan hệ (ngầu hơn!)
    $user->posts()->create([
        'title' => 'Bài viết thứ hai của John',
        'content' => 'Nội dung bài viết thứ hai.',
        'published_at' => now(),
    ]);
    
  2. Read (Đọc/Truy vấn):

    use App\Models\User;
    use App\Models\Post;
    
    // Lấy tất cả người dùng
    $users = User::all();
    
    // Tìm người dùng theo ID
    $john = User::find(1); // Trả về null nếu không tìm thấy
    $jane = User::findOrFail(2); // Ném exception nếu không tìm thấy
    
    // Tìm bài viết theo điều kiện
    $publishedPosts = Post::where('published_at', '<=', now())
                          ->orderBy('published_at', 'desc')
                          ->get();
    
    // Lấy một bài viết duy nhất
    $singlePost = Post::where('title', 'LIKE', '%đầu tiên%')->first();
    
    // Truy cập các thuộc tính
    if ($singlePost) {
        echo $singlePost->title; // "Bài viết đầu tiên của tôi"
        echo $singlePost->content;
        echo $singlePost->short_content; // Sử dụng accessor!
    }
    
  3. Update (Cập nhật):

    use App\Models\User;
    
    $user = User::find(1);
    if ($user) {
        $user->name = 'Johnathan Doe';
        $user->email = 'johnathan.doe@example.com';
        $user->save(); // Lưu thay đổi vào database
    
        // Cập nhật nhiều trường cùng lúc
        $user->update([
            'email' => 'new.johnathan@example.com'
        ]);
    }
    
    // Cập nhật nhiều bản ghi một lúc
    Post::where('published_at', null)->update(['published_at' => now()]);
    
  4. Delete (Xóa):

    use App\Models\Post;
    
    $post = Post::find(1);
    if ($post) {
        $post->delete(); // Xóa bản ghi có ID là 1
    }
    
    // Xóa nhiều bản ghi theo điều kiện
    Post::where('published_at', '<', '2023-01-01')->delete();
    

Quan Hệ (Relationships): Khi Các 'Sứ Giả' Bắt Đầu Kết Nối Với Nhau

Đây là phần khiến Model trở nên "sống động" và mạnh mẽ. Hãy tưởng tượng Model là các "đại sứ", và relationships là những "hiệp ước ngoại giao" giữa họ.

  • User có nhiều Post (One-to-Many): Trong User.php:

    public function posts()
    {
        return $this->hasMany(Post::class);
    }
    

    Sử dụng:

    $user = User::find(1);
    foreach ($user->posts as $post) {
        echo $post->title . "\n";
    }
    
  • Post thuộc về một User (Many-to-One): Trong Post.php:

    public function user()
    {
        return $this->belongsTo(User::class);
    }
    

    Sử dụng:

    Gợi Ý Đọc Tiếp
    Hướng dẫn Middleware_Laravel - Lavarel

    3 Lượt xem

    $post = Post::find(1);
    echo $post->user->name; // Lấy tên người tạo bài viết
    

Accessors & Mutators: 'Sứ Giả' Khoe Sắc Hay Thay Đổi Dung Nhan

Đây là cách bạn "biến hóa" dữ liệu khi đọc ra hoặc trước khi lưu vào database.

  • Accessor (Getter): Định nghĩa một phương thức get{AttributeName}Attribute. Ví dụ, lấy tên đầy đủ từ first_namelast_name (giả sử bảng users có 2 trường này).

    Trong User.php:

    public function getFullNameAttribute()
    {
        return "{$this->first_name} {$this->last_name}";
    }
    

    Sử dụng:

    $user = User::find(1);
    echo $user->full_name; // Truy cập như một thuộc tính bình thường
    
  • Mutator (Setter): Định nghĩa một phương thức set{AttributeName}Attribute. Ví dụ, tự động viết hoa tên khi lưu.

    Trong User.php:

    public function setFirstNameAttribute($value)
    {
        $this->attributes['first_name'] = ucfirst($value);
    }
    

    Sử dụng:

    $user = User::find(1);
    $user->first_name = 'john'; // Sẽ tự động lưu thành 'John'
    $user->save();
    

Mẹo Vặt & Best Practices: 'Bí Kíp Luyện Rồng' Để Thành Thạo Model

Để trở thành một "cao thủ" điều khiển các "sứ giả" dữ liệu, bạn cần nắm vững vài bí kíp sau:

  1. Quy Tắc Đặt Tên (Naming Conventions): Laravel rất "thông minh" trong việc suy luận tên bảng từ tên Model.

    • Model: Luôn là danh từ số ít, viết hoa chữ cái đầu (PascalCase), ví dụ: User, Product, BlogPost.
    • Table: Luôn là danh từ số nhiều, viết thường, dùng dấu gạch dưới (snake_case) nếu có nhiều từ, ví dụ: users, products, blog_posts.
    • Primary Key: Mặc định là id.
    • Foreign Key: Mặc định là tên_model_số_ít_id, ví dụ: user_id, post_id.
    • Timestamp: Mặc định là created_atupdated_at. Nếu bạn tuân thủ các quy tắc này, Laravel sẽ tự động làm mọi thứ cho bạn mà không cần cấu hình thêm.
  2. $fillable vs. $guarded: "Cảnh Cổng An Ninh" Của Dữ Liệu: Đây là một trong những tính năng bảo mật quan trọng nhất của Model. Nó giúp ngăn chặn lỗ hổng "Mass Assignment Vulnerability".

    • $fillable: Một mảng chứa tất cả các thuộc tính được phép gán giá trị hàng loạt (khi dùng create() hoặc update() với một mảng dữ liệu). Hãy luôn dùng $fillable để chỉ rõ những gì được phép.
    • $guarded: Một mảng chứa các thuộc tính không được phép gán giá trị hàng loạt. Nếu bạn để $guarded = [], tất cả các thuộc tính đều được phép gán hàng loạt. Thường thì $fillable được ưu tiên hơn vì nó minh bạch và an toàn hơn.
    // Trong Post.php
    protected $fillable = [
        'user_id',
        'title',
        'content',
        'published_at',
    ];
    // Không thêm 'id' hoặc 'created_at' vào đây!
    
  3. Eager Loading (Sử dụng with()): "Tránh Hội Chứng N+1 Query": Đây là một lỗi hiệu năng kinh điển mà nhiều người mới mắc phải. Khi bạn truy vấn một danh sách bài viết, sau đó trong vòng lặp lại đi truy vấn tên người dùng cho từng bài viết:

    $posts = Post::all(); // 1 query
    foreach ($posts as $post) {
        echo $post->user->name; // N query (mỗi bài viết 1 query để lấy user)
    }
    // Tổng cộng: 1 + N queries (N+1 problem)
    

    Để giải quyết, hãy dùng with() để "tải trước" các mối quan hệ:

    $posts = Post::with('user')->get(); // Chỉ 2 queries (1 cho posts, 1 cho users)
    foreach ($posts as $post) {
        echo $post->user->name; // User đã được tải sẵn, không có thêm query
    }
    

    Đây là một "chiêu thức" cực kỳ quan trọng để tối ưu hiệu năng ứng dụng.

  4. Scopes: "Bộ Lọc Thông Minh" Cho Truy Vấn: Scopes cho phép bạn định nghĩa các tập hợp truy vấn tái sử dụng được. Rất tiện lợi khi bạn có những điều kiện truy vấn lặp đi lặp lại.

    // Trong Post.php
    public function scopePublished($query)
    {
        return $query->where('published_at', '<=', now());
    }
    
    public function scopePopular($query)
    {
        return $query->where('views', '>', 1000);
    }
    

    Sử dụng:

    $publishedPosts = Post::published()->get();
    $popularPublishedPosts = Post::published()->popular()->get();
    
  5. Events và Observers: "Khi Dữ Liệu Tự Động Hành Động": Model có thể phát ra các sự kiện khi được tạo, cập nhật, xóa (creating, created, updating, updated, deleting, deleted, v.v.). Bạn có thể lắng nghe các sự kiện này để thực hiện các hành động tự động (ví dụ: gửi email xác nhận khi người dùng mới được tạo, xóa các file liên quan khi một bài viết bị xóa). Observers giúp gom logic xử lý sự kiện vào một lớp duy nhất.

  6. Docblocks cho Model: Tuy không trực tiếp ảnh hưởng đến hoạt động của code, nhưng việc thêm Docblocks (PHP DocBlocks) với @property@method cho các thuộc tính và mối quan hệ sẽ giúp IDE (như PhpStorm) cung cấp gợi ý tự động (autocompletion) tốt hơn, giúp bạn code nhanh và ít lỗi hơn.

    /**
     * @property int $id
     * @property string $name
     * @property string $email
     * @property \Illuminate\Support\Carbon|null $email_verified_at
     * @property string $password
     * @property string|null $remember_token
     * @property \Illuminate\Support\Carbon|null $created_at
     * @property \Illuminate\Support\Carbon|null $updated_at
     * @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\Post[] $posts
     * @property-read int|null $posts_count
     * @method static \Illuminate\Database\Eloquent\Builder|User newModelQuery()
     * @method static \Illuminate\Database\Eloquent\Builder|User newQuery()
     * @method static \Illuminate\Database\Eloquent\Builder|User query()
     * @mixin \Eloquent
     */
    class User extends Authenticatable
    {
        // ...
    }
    
  7. Model không phải là nơi chứa mọi logic: Mặc dù Model có thể chứa logic nghiệp vụ, nhưng hãy cẩn thận đừng biến nó thành một "God Object" (đối tượng chứa quá nhiều trách nhiệm). Các logic phức tạp, độc lập với dữ liệu cụ thể của Model, nên được tách ra thành các Service Class, Repository Pattern, hay Action Class để giữ cho Model được gọn gàng và dễ bảo trì.


Như vậy, Model trong Laravel không chỉ là một công cụ để tương tác với database, mà nó còn là một phần thiết yếu trong kiến trúc ứng dụng của bạn, giúp tổ chức code một cách logic, dễ đọc, dễ bảo trì và mạnh mẽ. Nắm vững Model là bạn đã nắm được một nửa sức mạnh của Laravel rồi đó! Hãy thực hành nhiều để các "sứ giả" dữ liệu này trở thành những trợ thủ đắc lực của bạn nhé!

Thuộc Series: Lavarel

Bài giảng này được tự động xuất bản ngẫu nhiên từ thư viện kiến thức. Đừng quên đón xem các Từ khoá Hướng Dẫn tiếp theo nhé!

#tech #cyberpunk #laravel
Chỉnh sửa bài viết

Bình luận (0)

Vui lòng Đăng Nhập để Bình luận

Hỗ trợ Markdown cơ bản
Nguyễn Văn A
1 ngày trước

Tính năng này đỉnh quá ad ơi, chờ mãi mới thấy một blog Tiếng Việt có UI/UX xịn như vầy!