Reputation: 8663
HTML form has select dropdown with list of existing categories and no category with id=0. CategoryStoreRequest must check if the category_id from the form belongs to existing category or is 0
Something like that
public function rules() {
return [
"name" => "required|min:3",
"category_id" => "required|exists:categories,id,except_if_value_is_0"
];
}
What is the most elegant way to achieve it?
Upvotes: 7
Views: 13359
Reputation: 11
The nullable
rule is an excellent way to handle this scenario. However, I faced a similar issue where I needed to update multiple database entries at once, so I needed more powerful solution with the following requirements:
null
, so it remains unchanged for all entries.'0'
, so the '0'
should also be valid.exists
in the entries
database table.Here’s how I resolved it (I used Laravel 11.33.2):
[
'entry_id' => [
'nullable',
Rule::in(['0', ...EntryModel::select('id')->get()->pluck('id')])
]
]
For more details, see the Laravel Validation Documentation.
Upvotes: 0
Reputation: 41
you can create new validation to handle see this example: in your_project_name/app/providers/AppServicesProviders.php
Validator::extend(
'exists_or_null',
function ($attribute, $value, $parameters)
{
if($value == 0 || is_null($value)) {
return true;
} else {
$validator = Validator::make([$attribute => $value], [
$attribute => 'exists:' . implode(",", $parameters)
]);
return !$validator->fails();
}
}
);
in your example do that
public function rules() {
return [
"name" => "required|min:3",
"category_id" => "required|exists_or_null:categories,id"
];
}
Upvotes: 4
Reputation: 7289
Instead of checking for exists or 0
, you could set your custom zero value to NULL
or an empty string.
You need to change a little bit of your logic, but then you can validate it correctly by using the sometimes rule:
public function rules() {
return [
"name" => "required|min:3",
"category_id" => "sometimes|exists:categories,id"
];
}
Upvotes: 2
Reputation: 8663
It turns out that nullable
is one quite elegant way to do it. When submitting the form then category_id array key is still present but its value is null. nullable allows the key to be null also.
public function rules() {
return [
"name" => "required|min:3",
"category_id" => "nullable|exists:categories,id"
];
}
In addition the select value must be ""
<select name="category_id">
<option value="">No category selection</option>
<option value="1">Cat 1</option>
</select>
Upvotes: 14
Reputation: 5796
You can use sometimes
. In this case, the rule will only be applied if a filled category_id is submitted.
public function rules() {
return [
"name" => "required|min:3",
"category_id" => "sometimes|exists:categories,id"
];
}
Change your html, so that there's no value set:
<select name="category_id">
<option value="">No category selection</option>
<option value="1">Cat 1</option>
</select>
Upvotes: 3