Laravel: How to use the ignore rule in Form Request Validation
To use the except
clause of the unique
rule, we need to provide the value of the field on the record that we want the rule to ignore directly in the rule itself.
So, if we want a unique name
field for every record except for on the record that the request updates, we need to add the value of the ID field to ignore:
class UpdateShopRequest extends FormRequest
{
...
public function rules()
{
return [
'shop.name' => 'unique:shops,name,' . $this->shop['id'],
];
}
}
As shown, this rule will cause validation to fail if any row contains the same shop name unless the row's id
matches $this->shop['id']
. This example assumes that our form contains a nested input field for the record's ID attribute because this particular question is performing validation on an array input:
<input type="hidden" name="shop[id]" value="{{ $shop->id }}">
...which lets us fetch the value within the request like we can with any other request.
However, most forms do not contain arrays, so—in other cases—the validation rule will likely refer to the input field directly (without nested identifiers):
'name' => 'unique:shops,name,' . $this->id,
More typically, we pass the record ID as a route parameter, which we can retrieve using the request's route()
method:
'name' => 'unique:shops,name,' . $this->route('id'),
...which works if we have a route defined similarly to:
Route::post('shops/{id}', ...);
The fourth parameter to the unique
validation rule lets us specify which column the except
clause applies to, and defaults to id
, so we can leave it off if we're just comparing the record's ID.
The rule looks a bit clumsy when we just concatenate the column value, especially for a field with a lot of other rules. Since version 5.3, Laravel provides a more elegant syntax to create a unique
rule with an except
clause:
use Illuminate\Validation\Rule;
...
return [
'name' => [
'required',
'string',
'max:100',
Rule::unique('shops', 'name')->ignore($this->id, 'optional_column'),
],
];
This example assumes that our form contains an array input field for the record's ID attribute because the question is performing validation on an array input:
<input type="hidden" name="shop[id]" value="{{ $shop->id }}">
Laravel 5.8: I've tried you solution right now, without adding the input, it's working well. Because Laravel pass the Shop object into request (shown with dd() into rules() )
Just:
`public function rules()
{
return [
'name' => 'unique:shops,name,'.$this->shop->id
];
}`