Get in touch
or send us a question?
CONTACT

20 thủ thuật Laravel Eloquent ORM (Phần 1)

Eloquent ORM trong Laravel thoạt nhìn có vẻ như đơn giản nhưng ẩn sâu dưới lớp vỏ bọc đó là nhiều chức năng bí ẩn nhưng lại ít được biết đến. Trong bài viết này mình sẽ giới thiệu đến các bạn 20 trong số những chức năng thú vị nhưng mạnh mẽ đó.

1. Increments and Decrements

Khi chúng ta cần increments một trường của một record, có thể bạn sẽ sử dụng một đoạn code như thế này:

$article = Article::find($article_id);
$article->read_count++;
$article->save();

Bạn có thể thay nó bằng đoạn code sau:

$article = Article::find($article_id);
$article->increment('read_count');

Ngoài ra, mọi thứ cũng sẽ hoạt động tốt nếu như bạn sử dụng:

Article::find($article_id)->increment('read_count');
Article::find($article_id)->increment('read_count', 10); // +10
Product::find($produce_id)->decrement('stock'); // -1

2. XorY methods

Eloquent có khá nhiều chức năng kết hợp hai phương thức. Có thể hiểu đơn giản nó như là: “hãy làm cho tôi việc X nhé, nếu không được thì làm Y giúp tôi”.

Ví dụ 1- findOrFail():

Thay vì sử dụng:

$user = User::find($id);
if (!$user) { abort (404); }

Hãy làm đơn giản hơn:

$user = User::findOrFail($id);

Chắc hẳn phương thức trên cũng đã quá quen thuộc với chúng ta rồi.

Ví dụ 2 – firstOrCreate():

Khi bạn cần tìm một record có thuộc tính thỏa mãn một điều kiện, nếu không tìm thấy thì sẽ tạo mới một record với chính thuộc tính đó:

$user = User::where('email', $email)->first();
if (!$user) {
  User::create([
    'email' => $email
  ]);
}

Mọi thứ chạy tốt và cũng dễ hiểu nhưng chúng ta có thể làm ngắn hơn:

$user = User::firstOrCreate(['email' => $email]);

3. Model boot() method

Trong mô hình Eloquent, khi bạn muốn override những phương thức mặc định của một model, hãy làm nó ở trong boot():

class User extends Model
{
    public static function boot()
    {
        parent::boot();
        static::updating(function($model)
        {
            // override some logging
        });
    }
}

Có lẽ một trong những ví dụ phổ biến nhất là khi bạn muốn đặt giá trị cho một trường nào đó tại thời điểm tạo mới một model object:

public static function boot()
{
  parent::boot();
  self::creating(function ($model) {
    $model->uuid = (string)Uuid::generate();
  });
}

4. Relationship with conditions and ordering

Đây là cách mà chúng ta thường dùng để định nghĩa một quan hệ:

public function users() {
    return $this->hasMany('App\User');    
}

Nhưng bạn có biết chúng ta cũng có thể tạo ra một quan hệ khác bằng việc kết hợp thêm điều kiện vào quan hệ ban đầu hay không?

Cụ thể, nếu như bạn muốn có một quan hệ chỉ bao gồm các users có trạng thái approved và được order theo email thì bạn có thể làm như sau:

public function approvedUsers() {
    return $this->hasMany('App\User')->where('approved', 1)->orderBy('email');
}

5. Model properties: timestamps, appends etc.

Có một vài tham số của một Eloquent model, chúng được thể hiện dưới dạng các thuộc tính trong class. Các tham số phổ biến nhất có lẽ là:

class User extends Model {
    protected $table = 'users';
    protected $fillable = ['email', 'password']; // which fields can be filled with User::create()
    protected $dates = ['created_at', 'deleted_at']; // which fields will be Carbon-ized
    protected $appends = ['field1', 'field2']; // additional values returned in JSON
}

Nhưng cũng còn nhiều thứ khác nữa:

protected $primaryKey = 'uuid'; // it doesn't have to be "id"
public $incrementing = false; // and it doesn't even have to be auto-incrementing!
protected $perPage = 25; // Yes, you can override pagination count PER MODEL (default 15)
const CREATED_AT = 'created_at';
const UPDATED_AT = 'updated_at'; // Yes, even those names can be overridden
public $timestamps = false; // or even not used at all

Đó là những thuộc tính theo tôi là thú vị nhất. Để tìm hiểu thêm các bạn có thể kiểm tra code của các abstract Model class và xem chúng đã sử dụng những gì.

Nguồn bài viết: 20 Laravel Eloquent Tips and Tricks

Leave a Reply

Your email address will not be published. Required fields are marked *