Tìm kiếm bài viết

Laravel: 20 mẹo và thủ thuật về Laravel Eloquent (Bài 2)

01.09.2020

0/5 (0 Reviews)

hướng dẫn tối ưu hoá Hiệu xuất hoạt động của Laravel nhằm tăng tốc độ xử lý của website, nếu bạn đang thiết kế website bằng Laravel thì đây quả thật là 1 bài viết hữu ích đấy.

    hướng dẫn tối ưu hoá Hiệu xuất hoạt động của Laravel nhằm tăng tốc độ xử lý của website, nếu bạn đang thiết kế website bằng Laravel thì đây quả thật là 1 bài viết hữu ích đấy.

    BelongsTo Default Models

    Hãy xem bạn có Post phụ thuộc vào Author và ở Blade code của bạn:

    {{ $post->author->name }}
    

    Nhưng điều gì sẽ xảy ra nếu author bị xóa, hoặc không được xét vì 1 vài lý do? Bạn sẽ gặp 1 error, một cái gì đó giống như “property of non-object”. Dĩ nhiên, bạn có thể ngăn chặn nó bằng cách:

    {{ $post->author->name ?? '' }}
    

    Tuy nhiên, bạn có thể thực hiện nó trên Eloquent relationship:

    public function author()
    {
        return $this->belongsTo('App\Author')->withDefault();
    }
    

    Trong ví dụ này, author() relation sẽ trả về một empty App\Author model nếu không có author nào được đính kèm vào bài đăng.

    Hơn nữa, chúng ta có thể gán các giá trị default property cho default model đó.

    public function author()
    {
        return $this->belongsTo('App\Author')->withDefault([
            'name' => 'Guest Author'
        ]);
    }
    

    Order by Mutator

    Hãy tưởng tượng bạn có điều này:

    function getFullNameAttribute()
    {
      return $this->attributes['first_name'] . ' ' . $this->attributes['last_name'];
    }
    

    Bây giờ, bạn muốn order by theo full_name? Nó sẽ không hoạt động:

    $clients = Client::orderBy('full_name')->get(); // doesn't work
    

    Giải pháp khá đơn giản. Chúng ta cần order kết quả sau khi chúng ta get chúng:

    $clients = Client::get()->sortBy('full_name'); // works!
    

    Lưu ý tên function là khác nhau, nó không phải là orderBy mà nó là sortBy.

    Default ordering in global scope

    Điều gì sẽ xảy ra nếu bạn muốn User::all() luôn được sắp xếp theo field name? Bạn có thể chỉ định một global scope. Hãy quay lại method boot() mà chúng ta đã đề cập ở trên.

    protected static function boot()
    {
        parent::boot();
    
        // Order by name ASC
        static::addGlobalScope('order', function (Builder $builder) {
            $builder->orderBy('name', 'asc');
        });
    }
    

    Đọ thêm về .

    Raw query methods

    Đôi khi chúng ta cần thêm raw query vào Eloquent statement của chúng ta. May mắn, có functions cho điều này:

    // whereRaw
    $orders = DB::table('orders')
        ->whereRaw('price > IF(state = "TX", ?, 100)', [200])
        ->get();
    
    // havingRaw
    Product::groupBy('category_id')->havingRaw('COUNT(*) > 1')->get();
    
    // orderByRaw
    User::where('created_at', '>', '2016-01-01')
      ->orderByRaw('(updated_at - created_at) desc')
      ->get();
    

    Replicate: make a copy of a row

    Không cần phải giải thích sâu, ở đây, cách tốt nhất để tạo một bản sao của cơ sở dữ liệu:

    $task = Tasks::find(1);
    $newTask = $task->replicate();
    $newTask->save();
    

    Chunk() method for big tables

    Không chính xác là Eloquent related, nó hơn về Collection, nhưng vẫn mạnh mẽ để xử lý các bộ dữ liệu lớn hơn, bạn có thể chia nhỏ chúng thành từng mảnh.

    Thay vì:

    $users = User::all();
    foreach ($users as $user) {
        // ...
    

    Bạn có thể làm:

    User::chunk(100, function ($users) {
        foreach ($users as $user) {
            // ...
        }
    });
    

    Create additional things when creating a model

    Tất cả chúng ta đều biết câu lệnh Artisan này:

    php artisan make:model Company
    

    Nhưng bạn có biết có 3 flags hữu ích để generate các file có liên quan tới model?

    php artisan make:model Company -mcr
    
    • -m sẽ tạo 1 migration file
    • -c sẽ tạo 1 controller
    • -r sẽ chỉ định rằng controller đó thành resourceful

    Override updated_at when saving

    Bạn có biết phương thức save() có thể chấp nhận các parameter không? Kết quả là chúng ta có thể nói với nó về việc "ignore" updated_at chức năng mặc định để được fill vào với timestamp hiện tại. Hãy xem:

    $product = Product::find($id);
    $product->updated_at = '2019-01-01 10:00:00';
    $product->save(['timestamps' => false]);
    

    Ở đây, chúng ta đã ghi đè default updated_at với define được xác định trước.

    Kết quả của hàm update() là gì?

    Bạn đã bao giờ tự hỏi những gì code này thực sự return?

    $result = $products->whereNull('category_id')->update(['category_id' => 2]);
    

    Ý tôi là, update được thực hiện trong cơ sở dữ liệu, nhưng biến $result chứa những gì?

    Câu trả lời là nhiều rows bị thay đổi, Vì vậy, nếu bạn cần kiểm tra xem có bao nhiêu row bị ảnh hưởng, bạn không cần phải gọi bất cứ điều gì khác ngoài phương thức update(), nó sẽ trả về cho bạn con số này.

    Transform brackets bên trong Eloquent query

    Điều gì xảy ra nếu bạn có and-or mix trong SQL query của bạn, giống như thế này:

    ... WHERE (gender = 'Male' and age >= 18) or (gender = 'Female' and age >= 65)
    

    Làm thế nào để dịch nó sang Eloquent? đây là 1 cách sai:

    $q->where('gender', 'Male');
    $q->orWhere('age', '>=', 18);
    $q->where('gender', 'Female');
    $q->orWhere('age', '>=', 65);
    

    Order sẽ không chính xác. Cách đúng phức tap hơn một chút, sử dụng các hàm clossure như sub-queries:

    $q->where(function ($query) {
        $query->where('gender', 'Male')
            ->where('age', '>=', 18);
    })->orWhere(function($query) {
        $query->where('gender', 'Female')
            ->where('age', '>=', 65); 
    })
    

    orWhere với nhiều giá trị

    Cuối cùng, bạn có thể pass một array của paramenter vào orWhere(). Cách thông thường:

    $q->where('a', 1);
    $q->orWhere('b', 2);
    $q->orWhere('c', 3);
    

    Bạn có thể làm nó giống như sau:

    $q->where('a', 1);
    $q->orWhere(['b' => 2, 'c' => 3]);
    

    Hy vọng những chia sẻ trên có thể giúp bạn có giúp ích cho bạn trong việc lập trình với Laravel.

    Chúc các bạn học tốt làm chủ Laravel

    CÓ THỂ BẠN QUAN TÂM

    Bài Viết Cùng Chuyên Mục

    XEM THÊM
    thumbnail

    Kubernetes bài 6 - Vận hành k8s Day-Two Operations và Quản trị bằng GitOps

    22.05.2026

    Khi cụm Kubernetes của bạn đã được bảo mật cấu hình, tối ưu tài nguyên và thiết lập tự phục hồi, câu hỏi đặt ra là làm sao để duy trì sự ổn định đó trong nhiều năm tiếp theo mà không bị phụ thuộc

    thumbnail

    Kubernetes bài 5 - bảo mật Cloud Native và chuẩn DevSecOps cho K8s

    22.05.2026

    Việc siết chặt an ninh (Hardening) không phải là cấu hình một vài thông số rồi bỏ đó, mà là một tư duy phòng thủ chiều sâu.

    thumbnail

    Kubernetes bài 4 - Tối ưu Resource Auto-Healing và Scale Zero-Downtime

    22.05.2026

    Bài viết này sẽ đi sâu vào các cơ chế ở tầng Kernel giúp hệ thống tự phục hồi, chống lại các đợt tấn công cạn kiệt tài nguyên và cập nhật phiên bản mới mà người dùng không hề hay biết.

    thumbnail

    Kubernetes bài 3 - Bảo mật cấu hình k8s và config Security trên Production

    22.05.2026

    Kubernetes giải quyết bài toán này bằng hai đối tượng chuyên biệt nhưng nếu không hiểu rõ bản chất bảo mật ở tầng dưới, bạn đang tự tay dâng toàn bộ chìa khóa hệ thống cho hacker.

    thumbnail

    Kubernetes bài 2 - Mạng lưới k8s và luồng Traffic ở Packet Level

    22.05.2026

    Pod không chỉ là một container: Rất nhiều người nhầm lẫn Pod 1-1 với Container. Thực chất, Pod là đơn vị triển khai nhỏ nhất, có thể chứa một hoặc nhiều container

    Mục lục bài viết