When validating forms or API requests, sometimes the rule for one field depends on values from other fields. In this tutorial, I will show you 4 different Laravel syntax examples to achieve it.
1. Rule required_if
Let's say we have the following scenario:
If the post status is draft only the title is required, and if the status is published
then title
and content
is required.
The form for this example has the following content:
resources/views/posts/create.blade.php
<div class="p-6 text-gray-900"> <div class="text-green-600">{{ session('status') }}</div> <form action="{{ route('posts.store') }}" method="post" class="flex flex-col gap-4"> @csrf <div class="flex flex-col gap-2"> <label for="title">Title</label> <input id="title" name="title" type="text" value="{{ old('title') }}" /> @error('title') <div class="text-red-600">{{ $message }}</div> @enderror </div> <div class="flex flex-col gap-2"> <label for="content">Content</label> <textarea id="content" name="content">{{ old('content') }}</textarea> @error('content') <div class="text-red-600">{{ $message }}</div> @enderror </div> <div class="flex flex-col gap-2"> <label for="status">Status</label> <select id="status" name="status"> <option value="draft" {{ old('status') == 'draft' ? 'selected' : '' }}>Draft</option> <option value="published" {{ old('status') == 'published' ? 'selected' : '' }}>Published</option> </select> @error('status') <div class="text-red-600">{{ $message }}</div> @enderror </div> <div> <button class="px-3 py-2 bg-blue-800 text-white rounded">Submit</button> </div> </form></div>
The Controller method is pretty straightforward:
app/Http/Controllers/PostController.php
public function store(StorePostRequest $request){ Post::create($request->validated()); return to_route('posts.create')->withStatus('Created.');}
Then we can define our rules like this:
app/Http/Requests/StorePostRequest.php
namespace App\Http\Requests; use Illuminate\Foundation\Http\FormRequest; class StorePostRequest extends FormRequest{ public function authorize(): bool { return true; } public function rules(): array { return [ 'title' => ['required', 'string', 'max:255'], 'content' => ['required_if:status,published'], 'status' => ['required', 'in:draft,published'], ]; }}
The result if we have selected draft
status and try to submit the form:
And if we have the status published
:
The required_if
rule can accept a lot more conditions, the format is as follows:
required_if:field,value,field,value...
It is suitable if validation depends on values of the other fields.
2. Rule required_with
Now let's say we need the author's name field to be filled in when we have some content present.
Add the author field to the form:
resources/views/posts/create.blade.php
{{-- ... --}} <div class="flex flex-col gap-2"> <label for="author">Author</label> <input id="author" name="author" type="text" value="{{ old('author') }}" /> @error('author') <div class="text-red-600">{{ $message }}</div> @enderror</div>
And new validation rule:
app/Http/Requests/StorePostRequest.php
// ... public function rules(): array{ return [ 'title' => ['required', 'string', 'max:255'], 'content' => ['required_if:status,published'], 'status' => ['required', 'in:draft,published'], 'author' => ['required_with:content'], ];}
Now author
field will be required always if there is some content
regardless of the status
value.
When using the required_with
rule, the field under validation must be present and not empty only if any of the other specified fields are present and not empty.
3. Rule::when() method
Rule::when($condition, $rules, $defaultRules = [])
is useful when you want to add rules conditionally, for example, to allow publishing during work hours:
app/Http/Requests/StorePostRequest.php
use Illuminate\Validation\Rule; //... public function rules(): array{ return [ 'title' => ['required', 'string', 'max:255'], 'content' => ['required_if:status,published'], 'status' => [ 'required', Rule::when( now()->between('9:00', '17:00'), 'in:draft,published', 'in:draft' ), ], 'author' => ['required_with:content'], ];}
4. Rule::requiredIf() method
The Rule::requiredIf($callable|bool $callback)
method can be used to construct a more complex condition by adding your custom logic:
app/Http/Requests/StorePostRequest.php
use Illuminate\Validation\Rule; //... public function rules(): array{ return [ 'title' => ['required', 'string', 'max:255'], 'content' => [Rule::requiredIf(function () { return $this->input('status') == 'published'; })], 'status' => [ 'required', Rule::when( now()->between('9:00', '17:00'), 'in:draft,published', 'in:draft' ), ], 'author' => ['required_with:content'], ];}
More information on all conditional rules can be found on Laravel Validation Docs
You also may be interested in a related PREMIUM course: Laravel Array Validation: All You Need To Know
thank you