Thats all, folks. Please let me know, what you think about this approach in the comments.
Posted on: December 16, 2023 01:44 AM
Posted by: Renato
Views: 195
A better place for your validation rules in Laravel
...
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
<?php namespace App\Http\Controllers; | |
use App\Http\Controllers\Controller; | |
class PostController extends Controller | |
{ | |
public function store(Request $request) | |
{ | |
$validatedData = $request->validate([ | |
'title' => 'required|unique:posts|max:255', | |
'body' => 'required', | |
]); | |
// The blog post is valid... | |
} | |
} |
.....
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.
Form Request Validation
...
<?php namespace App\Http\Requests; | |
use Illuminate\Foundation\Http\FormRequest; | |
class PostStoreRequest extends FormRequest | |
{ | |
public function authorize() | |
{ | |
return true; | |
} | |
public function rules() | |
{ | |
return [ | |
'title' => 'required|unique:posts|max:255', | |
'body' => 'required', | |
]; | |
} | |
} -------------- |
<?php namespace App\Http\Controllers; | |
use App\Http\Controllers\Controller; | |
use App\Http\Requests\SingingCircleRequest; | |
class PostController extends Controller | |
{ | |
public function store(PostStoreRequest $request) | |
{ | |
// You can just pull the data out of PostStoreRequest | |
} | |
} |
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. The downsides are:
- 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:
<?php namespace App\Models; | |
use Illuminate\Database\Eloquent\Model; | |
class BlogPost extends Model | |
{ | |
public static $createRules = [ | |
'title' => 'required|unique:posts|max:255', | |
'body' => 'required', | |
]; | |
public static $updateRules = [ | |
'title' => 'required|unique:posts|max:255', | |
'body' => 'required', | |
]; | |
} |
------------------------------------------------------------------------------------------------
<?php namespace App\Http\Controllers; | |
use App\Http\Controllers\Controller; | |
use App\Models\BlogPost; | |
class PostController extends Controller | |
{ | |
public function store(Request $request) | |
{ | |
$validatedData = $request->validate(BlogPost::$createRules); | |
// The blog post is valid... | |
} | |
} |
-----------------------------------------------------------------------
<?php namespace App\Http\Requests; | |
use App\Models\BlogPost; | |
use Illuminate\Foundation\Http\FormRequest; | |
class PostStoreRequest extends FormRequest | |
{ | |
public function rules() | |
{ | |
return BlogPost::$createRules | |
} | |
} |
--------------------------------------------------------------------
You can even go one step further and combine two or more rules together.
<?php namespace App\Http\Requests; | |
use App\Models\BlogPost; | |
use Illuminate\Foundation\Http\FormRequest; | |
class PostStoreRequest extends FormRequest | |
{ | |
public function rules() | |
{ | |
return array_merge(BlogPost::$createRules, Author::$createRules); | |
} | |
} |
.
Donate to Site
Renato
Developer