Fluent Validation Rules in Laravel 5.3

1.Giới thiệu

Tại phiên bản mới nhất của Laravel - 5.3, ngoài những thay đổi lớn về Notifications hay Advance Search With Laravel Scout,..., có một cải tiến nhỏ trong Validation Rules.

2.Case Study

Để xem sự thay đổi đó là gì, ta xét một trường hợp khá phổ biến sau: Khi tạo chức năng chỉnh sửa thông tin tài khoản người dùng, ta cần thẩm định các trường dữ liệu được nhập vào, ở ví dụ này là name và email, như sau:

...
public function update() {

    $this->validate(request(),[

        'name' => 'required',
        'email' => 'required|email|unique:users,email,' .auth()->id()

    ]);

}
...

Như định nghĩa validation rules ở trên, trường name và email đều không được bỏ trống, trường email phải nhập đúng email format và không được trùng với email nào đã tồn tại trong bảng users. .auth()->id() được sử dụng để bỏ qua người dùng hiện tại khi thẩm định tính duy nhất (unique). Điều này là hữu ích khi người dùng chỉ muốn đổi name và giữ nguyên email.

Tuy nhiên, với cách định nghĩa như trên, việc kiểm tra lại ngữ nghĩa của rules sau này khá vất vả. Ta sẽ khó có thể nhớ được rule trên dùng để thẩm định điều gì.Thay vào đó, ở phiên bản Laravel 5.3, ta có thể sử dụng một lớp mới có tên là Rule.Ta viết lại đoạn code trên như sau:

...
use Illuminate\Validation\Rule;
...
public function update() {

    $this->validate(request(),[

        'name' => 'required',
        //'email' => 'required|email|unique:users,email,' .auth()->id()
        'email' => [
            'required',
            'email',
            Rule::unique('users', 'email')
                ->ignore(auth()->id())
         ]

    ]);

}
...

Ở đoạn code trên, ta đã import lớp Illuminate\Validation\Rule. Hãy xem qua các hàm được định nghĩa tại lớp này.

<?php

namespace Illuminate\Validation;

use Illuminate\Support\Traits\Macroable;

class Rule
{
    use Macroable;

    // Get a dimensions constraint builder instance.
    public static function dimensions(array $constraints = [])
    {
        return new Rules\Dimensions($constraints);
    }

    // Get a exists constraint builder instance.
    public static function exists($table, $column = 'NULL')
    {
        return new Rules\Exists($table, $column);
    }

    // Get an in constraint builder instance.
    public static function in(array $values)
    {
        return new Rules\In($values);
    }

     // Get a not_in constraint builder instance.
    public static function notIn(array $values)
    {
        return new Rules\NotIn($values);
    }

    //Get a unique constraint builder instance.
    public static function unique($table, $column = 'NULL')
    {
        return new Rules\Unique($table, $column);
    }
}

Các hàm này khá giống với các rules mà ta đã biết từ trước với cùng chức năng.Chẳng hạn như hàm exists sẽ thẩm định dữ liệu nhập vào có tồn tại trong bảng hay không. Ngoài ra, ta có thể thấy ở hàm unique trả về một đối tượng Unique. Ta xem qua một số hàm được định nghĩa tại lớp Unique này.

<?php

namespace Illuminate\Validation\Rules;

use Closure;

class Unique
{
...
...
public function __construct($table, $column = 'NULL')
    {
        $this->table = $table;
        $this->column = $column;
    }

//Set a "where" constraint on the query.
public function where($column, $value = null)
    {
        if ($column instanceof Closure) {
            return $this->using($column);
        }

        $this->wheres[] = compact('column', 'value');

        return $this;
    }
...
...
//Convert the rule to a validation string.
public function __toString()
    {
        return rtrim(sprintf('unique:%s,%s,%s,%s,%s',
            $this->table,
            $this->column,
            $this->ignore ?: 'NULL',
            $this->idColumn,
            $this->formatWheres()
        ), ',');
    }
}

Tại đây ta để ý có hàm __toString, sẽ có chức năng chuyển đổi rule thành một chuỗi thẩm định tương ứng.

3.Tổng kết

Qua đây, ta có thể thấy việc sử dụng lớp Rule mới này sẽ giúp việc định nghĩa validation rules dễ dàng hơn bao giờ hết. Đồng thời, nó sẽ giúp ta hiểu và ghi nhớ code một cách tự nhiên và lâu dài hơn.

Tham khảo

Fluent Validation Rules - Laracast