6. Form request validation (ok)

https://viblo.asia/p/tap-20-validation-laravel-GrLZDWAEKk0

Với form request validation, ứng dụng của chúng ta sẽ có tính tách rời về mặt validate cho các controller để dễ dàng quản lý hay bảo trì. Với nó, ta có thể thực hiện các validation phức tạp hơn, cần inject các dependency mà không phải gọi quá nhiều ở controller.

1. Tạo form request (Creating form request)

Ở phần này mình sẽ sử dụng lại đoạn code trong phần AJAX request & validation cho blade view create_post.

Để tạo một form request, ta chỉ cần chạy lệnh Artisan sau:

php artisan make:request StorePost

Lớp này sẽ tạo tự động ở thư mục app/Http/Requests, mặc định thì thư mục này không tồn tại, nó sẽ tự động tạo trong khi chạy lệnh Artisan trên.

Các bạn mở form request App\Http\Requests\StorePost vừa tạo lên, quan sát sẽ thấy trong file có chứa hai method authorizerules. Trước tiên ta cần để ý đến method rules, tại đây ta sẽ trả về mảng chứa các valdation rule.

public function rules()
{
    return [
        'title' => 'required|max:100',
        'body' => 'required|min:50'
    ];        
}

Lưu ý: Bạn có thể type-hint bất kỳ class nào cần thiết cho việc xử lý mảng validation rule, service container sẽ tự động load cho bạn.

Vậy, làm sao để form request hoạt động? Việc của bạn rất đơn giản, chỉ cần type-hint tên class form request thay cho Request ở controller action. Mình sẽ lấy lại ví dụ trên để tích hợp form request vào, bạn chỉ cần mở file controller App\Http\Controllers\PostController và thay đổi nội dung bên trong method store như sau:

use App\Http\Requests\StorePost;

public function store(StorePost $request)
{
    $validated = $request->validated();
}

Với method validated trong object form request, hệ thống validate dựa trên các rule validtion mà ta đã khai báo ở form request. Method này cũng tương tự như validate của object request, nó sẽ trả về redirect response nếu gửi request với form truyền thống, trong khi sẽ gửi json response nếu gửi request với AJAX.

2. Ủy quyền form request (Authorizing form request)

Các bạn hãy nhìn hình bên dưới:

Đây là kết quả mà sau khi mình inject form request vào method store và chạy lại. Thay vì mình nhận mã lỗi 422, thì bây giờ lại là 403 cùng với thông báo "This action is unauthorize". Điều này có nghĩa là hiện tai chúng ta chưa được ủy quyền để gửi form request này đến controller store. Đến đây chắc các bạn còn nhớ method authorize chứ? Đúng vậy, method này sẽ quyết định rằng ta được quyền gửi form request đến controller hay là không với boolean true hoặc false.

Với method này, ta có thể ứng dụng để kiểm tra xem tài nguyên có thuộc về sở hữu của người dùng trong việc chỉnh sửa hoặc xóa tài nguyên. Chẳng hạn hệ thống sẽ kiểm tra ID bài viết có thuộc về quyền sở hữu của tác giả hay không để tiếp tục thực thi chỉnh sửa hoặc xóa bài viết.

Mặc định khi tạo form request thì method authorize sẽ trả về giá trị false, tức là chưa được ủy quyền. Tại method authorize, bạn có thể code các đoạn xử lý logic nào đó, miễn là cuối cùng trả về một trong hai giá trị true hoặc false.

Quay lại ví dụ trên, ta chỉ cần thay đổi giá trị trả về của method authorize thành true.

public function authorize()
{
    return true;
}

Một kết quả đầy mong đợi:

Lưu ý: Với method authorize, ta cũng dễ dàng type-hint một số dependency cần thiết cho việc xử lý logic để ủy quyền.

3. Adding After Hooks To Form Requests

Tiêu đề này khó dịch sát nghĩa nên mình sẽ để nguyên như Laravel Docs. Việc này sẽ giống như bạn có thể đính kèm một callback sau khi việc validation hoàn tất. Để làm được nó, bạn chỉ cần khai báo method withValidator trong form request với nội dung sau:

public function withValidator($validator)
{
    $validator->after(function ($validator) {
        // something
    }
}

hoặc bạn có thể lồng một câu điều kiện nào đó:

protected function isSomeThing(Dependency $object)
{
    //
}

public function withValidator($validator)
{
    $validator->after(function ($validator) {
        if ($this->isSomeThing()) {
            // something...
        }
    }
}

Chẳng hạn với ví dụ trên, mình sẽ thêm method withValidator cho form request StorePost như sau:

public function withValidator($validator) {
  $validator->after(function ($validator) {
    $validator->errors()->add('field', 'Something is wrong with this field!');
  });
}

Và đây là kết quả:

Last updated