Ein besserer Platz für die Validierungs-Regeln in Laravel | Arroba IT
Skip to content
php laravel

Ein besserer Platz für die Validierungs-Regeln in Laravel

Oct 27, 2017

Validation in Laravel is pretty easy. It basically gives you two options where to validate an incoming request:

  • inside a controller action

  • via a dedicated Form Request

In-Action validation

1<?php namespace App\Http\Controllers;
2 
3use App\Http\Controllers\Controller;
4 
5class PostController extends Controller
6{
7 public function store(Request $request)
8 {
9 $validatedData = $request->validate([
10 'title' => 'required|unique:posts|max:255',
11 'body' => 'required',
12 ]);
13 
14 // The blog post is valid...
15 }
16}

This is a pretty simple yet powerful approach. You just ask the request to validate itself based on the passed rules. If the validation fails, the method creates a proper error message and send it back to the view. If the validation passes, it just moves on with the rest of the code inside the action.

This can get very expressive if you validate a long form with more than 10 fields; but there is something we can do about.

Validierung via Form Request

1<?php namespace App\Http\Requests;
2 
3use Illuminate\Foundation\Http\FormRequest;
4 
5class PostStoreRequest extends FormRequest
6{
7 public function authorize()
8 {
9 return true;
10 }
11 
12 public function rules()
13 {
14 return [
15 'title' => 'required|unique:posts|max:255',
16 'body' => 'required',
17 ];
18 }
19}

1<?php namespace App\Http\Controllers;
2 
3use App\Http\Controllers\Controller;
4use App\Http\Requests\SingingCircleRequest;
5 
6class PostController extends Controller
7{
8 public function store(PostStoreRequest $request)
9 {
10 // You can just pull the data out of PostStoreRequest
11 }
12}

Here we need to create a Form Request object with a meaningful name.

$ php artisan make:request PostStoreRequest

Then, we define the rules in rules() and pass the Form Request object to the action. We are now able to get the validated data out of PostStoreRequest.
I am using In-Action validation for rapid development. I like to see the rules close to the code. In this phase I need to adjust them quickly without fiddling too much with several files.


In later state, I usually move them to a FormRequest class. The benefits are:

  • cleaner and shorter action

  • if the validation fails, the action will never hit

  • the Form Request object has a dedicated place to authorize the action

But where light is, is also some darkness:

  • a Form Request object for any action who handles user input

  • your validation rules are spread and are hidden in all these files

While the first point is just like it is, the last point can be addressed.

Move the rules to the model

Since we try to validate and store a blog post, we also have a BlogPost model. Fine! Now, just move the rules from where ever they are to the model and store them in a static variable:

1// Validate inside an action.
2<?php namespace App\Models;
3 
4use Illuminate\Database\Eloquent\Model;
5 
6class BlogPost extends Model
7{
8 public static $createRules = [
9 'title' => 'required|unique:posts|max:255',
10 'body' => 'required',
11 ];
12 
13 public static $updateRules = [
14 'title' => 'required|unique:posts|max:255',
15 'body' => 'required',
16 ];
17}

1// In-Action Validation with rules from Model
2<?php namespace App\Http\Controllers;
3 
4use App\Http\Controllers\Controller;
5use App\Models\BlogPost;
6 
7class PostController extends Controller
8{
9 public function store(Request $request)
10 {
11 $validatedData = $request->validate(BlogPost::$createRules);
12 // The blog post is valid...
13 }
14}

1// Form Request Validation with rules from Model
2<?php namespace App\Http\Requests;
3 
4use App\Models\BlogPost;
5use Illuminate\Foundation\Http\FormRequest;
6 
7class PostStoreRequest extends FormRequest
8{
9 public function rules()
10 {
11 return BlogPost::$createRules
12 }
13}

You can even go one step further and combine two or more rules together.

1<?php namespace App\Http\Requests;
2 
3use App\Models\BlogPost;
4use Illuminate\Foundation\Http\FormRequest;
5 
6class PostStoreRequest extends FormRequest
7{
8 public function rules()
9 {
10 return array_merge(BlogPost::$createRules, Author::$createRules);
11 }
12}