Writing rules() in a Form Request
The rules() method looks like a plain array of pipe-delimited strings, but each entry can just as easily be an array, a Rule object, or a closure. Here's what's available once the basic required|string|max:255 stops being enough.
-
String syntax vs array syntax
A pipe-delimited string and an array of rules mean exactly the same thing — the array form just avoids escaping when a rule's parameter contains a pipe or comma itself, like a regex.
public function rules(): array { return [ 'email' => 'required|email|max:255', // equivalent, array form 'email' => ['required', 'email', 'max:255'], ]; } -
Rule objects for anything dynamic
The
Rulefacade builds rules that need runtime values — like ignoring the current record's own row on anuniquecheck during an update.use Illuminate\Validation\Rule; public function rules(): array { return [ 'email' => [ 'required', 'email', Rule::unique('users')->ignore($this->user), ], 'status' => ['required', Rule::in(['draft', 'published', 'archived'])], ]; } -
Conditional rules
Some fields only need validating depending on other input.
sometimesskips a rule entirely when the field is absent from the request;Rule::when()and reading$this->input()handle everything more conditional than that, sincerules()is just a regular method.public function rules(): array { return [ 'promo_code' => 'sometimes|string|max:20', 'shipping_address' => [ Rule::requiredIf($this->input('delivery_method') === 'courier'), 'string', ], ]; } -
Custom messages and attribute names
Override
messages()to replace the default English copy for specificrule.fieldcombinations, andattributes()to control the field name that gets substituted into the:attributeplaceholder.public function messages(): array { return [ 'price.min' => 'The price can\'t be negative.', ]; } public function attributes(): array { return [ 'sku' => 'SKU', ]; } -
Validating nested and array input
Dot notation reaches into nested arrays, and
*applies the same rule to every item in a list — handy for a request with a repeated group of fields, like order line items.public function rules(): array { return [ 'items' => 'required|array|min:1', 'items.*.product_id' => 'required|integer|exists:products,id', 'items.*.quantity' => 'required|integer|min:1', ]; }