Custom check for uniqueness of more than one field in laravel
I have a table tanks
+----+----------+-------+-------+
| id | capacity | model | width |
+----+----------+-------+-------+
| 1 | 1000 | 15 | 960 |
| 2 | 50000 | 30 | 200 |
| 3 | 100 | 15 | 12 |
| 4 | 80000 | 40 | 100 |
| 5 | 1000 | 30 | 123 |
| 6 | 500 | 5 | 1213 |
| 7 | 1000 | 22 | 2234 |
+----+----------+-------+-------+
And I added a unique property to my table
ALTER TABLE `tanks`
ADD UNIQUE `capacity_model_width` (`capacity`, `model`, `width`);
And my value storage function looks like this:
public function store(Request $request) {
$image = new tank();
$this->validate($request, [
'capacity' => 'required|numeric',
'model' => 'required|numeric',
'width' => 'required|numeric',
]
);
$image->capacity = $request->capacity;
$image->model = $request->model;
$image->width = $request->width;
$image->save();
return redirect()->route('tank.index')
->with('success', 'Tank created successfully');
}
Now when I paste below error it shows
Integrity constraint violation: 1062 Duplicate entry
'1000-22-2234' for key 'capacity_model_width'
I need to show an error message in my submissions if they are unique. I am new to Laravel how to add custom validation and error message inside store function
+3
source to share
3 answers
Add this to your code
We're going to check if we need to create the fields we need first, then we connect them and add them to the query. We can now run our unique check
public function store(Request $request) {
$image = new tank();
//Check to see if fields exist then validate after concatenation
if(isset($request->capacity) && isset($request->model) && isset($request->width) ){
$request->request->add(['my_key' => ['capacity' => $request->capacity, 'model' => $request->model, 'width' => $request->width] ]);
}
$this->validate($request, [
'capacity' => 'required|numeric',
'model' => 'required|numeric',
'width' => 'required|numeric',
'my_key' => 'required|uniqueCapacity',
]
);
$image->capacity = $request->capacity;
$image->model = $request->model;
$image->width = $request->width;
$image->save();
return redirect()->route('tank.index')
->with('success', 'Tank created successfully');
}
Adding a custom validator
First go into your AppServiceProvider and add the following
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Validator::extend('uniqueCapacity', function ($attribute, $value, $parameters, $validator) {
$value_array = explode("-", $value);
$items = DB::select("SELECT count(*) as aggregate FROM tanks WHERE capacity ='$value_array[0]' AND model='$value_array[1]' AND width='$value_array[2]' ");
$number=$items[0]->aggregate;
if ($number > 0) {
return false;
} else {
return true;
}
});
}
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
//
}
}
+2
source to share
Add a unique validation rule as being that
$this->validate($request, [
'capacity' => 'required|numeric|unique:tanks,capacity',
'model' => 'required|numeric',
'width' => 'required|numeric',
]
);
And you can add additional places where
Validator::make($request, [
'capacity' => Rule::unique('tanks')->where(function ($query) use $request {
$query->where('capacity', $request->input('capacity'))->where('width', $request->input('width'))->where('model', $request->input('model'));
})
]);
0
source to share