Laravel: validate an integer field that needs to be greater than another
PhpLaravelLaravel 5Php Problem Overview
I have two fields that are optional only if both aren't present:
$rules = [
'initial_page' => 'required_with:end_page|integer|min:1|digits_between: 1,5',
'end_page' => 'required_with:initial_page|integer|min:2|digits_between:1,5'
];
Now, end_page
needs to be greater than initial_page
. How include this filter?
Php Solutions
Solution 1 - Php
There is no built-in validation that would let you compare field values like that in Laravel, so you'll need to implement a custom validator, that will let you reuse validation where needed. Luckily, Laravel makes writing custom validator really easy.
Start with defining new validator in yor AppServiceProvider:
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
Validator::extend('greater_than_field', function($attribute, $value, $parameters, $validator) {
$min_field = $parameters[0];
$data = $validator->getData();
$min_value = $data[$min_field];
return $value > $min_value;
});
Validator::replacer('greater_than_field', function($message, $attribute, $rule, $parameters) {
return str_replace(':field', $parameters[0], $message);
});
}
}
Now you can use your brand new validation rule in your $rules:
$rules = [
'initial_page' => 'required_with:end_page|integer|min:1|digits_between: 1,5',
'end_page' => 'required_with:initial_page|integer|greater_than_field:initial_page|digits_between:1,5'
];
You'll find more info about creating custom validators here: http://laravel.com/docs/5.1/validation#custom-validation-rules. They are easy to define and can then be used everywhere you validate your data.
Solution 2 - Php
the question was asked in 2015 so most of the answers are also outdated now in 2019
i want to give answer which uses features provided by laravel team which is included in it's new version,
so as stated by @Sarpadoruk as of laravel 5.6 laravel added features in validation like
gt
,gte
,lt
and lte
which means:
gt
- greater thangte
- greater than equal tolt
- less thanlte
- less than equal to
so using gt
you can check that your end_page should be greater than your initial_page and your task becomes very easy now:
$rules = [
'initial_page' => 'required_with:end_page|integer|min:1|digits_between: 1,5',
'end_page' => 'required_with:initial_page|integer|gt:initial_page|digits_between:1,5'
];
Solution 3 - Php
For Laravel 5.4 it will be:
$rules = ['end_page'=>'min:'.(int)$request->initial_page]
Solution 4 - Php
As of Laravel 5.6 gt
, gte
, lt
and lte
rules are added.
Solution 5 - Php
I think you can try something like this,
$init_page = Input::get('initial_page');
$rules = [
'initial_page' => 'required_with:end_page|integer|min:1|digits_between: 1,5',
'end_page' => 'required_with:initial_page|integer|min:'. ($init_page+1) .'|digits_between:1,5'
];
Solution 6 - Php
Why not just define $min_number = $min + 1
number and use validator min:$min_number
, example:
$min = intval($data['min_number']) + 1;
return ['max_number' => 'required|numeric|min:'.$min];
And you can then return custom error message to explain the error to user.
Solution 7 - Php
use gt = grater than :value|field
use gte = grater than equal :value|field
use lt = less than :value|field
use lte = less than equal :value|field
in your case it's
gt:initial_page
and the result will be
$rules = array(
'initial_page' => 'required_with:end_page|numeric|min:1|digits_between: 1,5',
'end_page' => 'required_with:initial_page|numeric|gt:initial_page|min:2|digits_between:1,5'
);
Solution 8 - Php
If you're maintaining a project on Laravel 5.2 then the following should backport the current gt rule for you:
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
Validator::extend('gt', function($attribute, $value, $parameters, $validator) {
$min_field = $parameters[0];
$data = $validator->getData();
$min_value = $data[$min_field];
return $value > $min_value;
});
Validator::replacer('gt', function($message, $attribute, $rule, $parameters) {
return sprintf('%s must be greater than %s', $attribute, $parameters[0]);
});
}
}
You can then use it as per the current documentation:
$rules = [
'end_page' => 'gt:initial_page'
];