Коли правила залежать від стану компонента чи потребують об'єктів правил Laravel, атрибутів #[Validate] замало - потрібен метод rules().
use Illuminate\Validation\Rule;
new class extends Component {
public ?Product $product = null;
public string $sku = '';
public string $type = 'physical';
public ?float $weight = null;
/** @var list<array{name: string, qty: int}> */
public array $items = [];
protected function rules(): array
{
return [
// унікальність, крім поточного запису при редагуванні
'sku' => ['required', Rule::unique('products', 'sku')->ignore($this->product)],
'type' => ['required', Rule::in(['physical', 'digital'])],
// умовне правило: вага обов'язкова лише для фізичних товарів
'weight' => [Rule::requiredIf($this->type === 'physical'), 'nullable', 'numeric', 'min:0'],
// масив рядків
'items' => ['array', 'min:1', 'max:50'],
'items.*.name' => ['required', 'string', 'max:100'],
'items.*.qty' => ['required', 'integer', 'min:1'],
];
}
protected function validationAttributes(): array
{
return ['items.*.qty' => 'кількість'];
}
};
Шаблон з динамічними рядками:
@foreach ($items as $index => $item)
<div wire:key="item-{{ $index }}">
<input wire:model="items.{{ $index }}.name">
@error("items.{$index}.name") <p>{{ $message }}</p> @enderror
</div>
@endforeach
<button type="button" wire:click="addItem">Додати рядок</button>
public function addItem(): void
{
if (count($this->items) < 50) {
$this->items[] = ['name' => '', 'qty' => 1];
}
}
Додавання через метод на сервері, а не через $set з браузера, дає змогу одразу обмежити кількість рядків.
Що варто знати:
rules()не перевіряється при введенні - лише в$this->validate(). Для перевірки в реальному часі - порожній#[Validate]над властивістю;- межі масиву обов'язкові (
max:50): масив приходить з браузера, і без обмеження хтось надішле сто тисяч елементів; - ключ
wire:keyдля рядків - бажано стабільний ідентифікатор, а не індекс, якщо рядки можна видаляти з середини списку; - помилки адресуються з індексом -
items.3.qty; messages()іvalidationAttributes()- власні тексти й назви полів; назвиrules,messages,validationAttributesзарезервовані - не використовуйте їх для властивостей;- власні правила (
php artisan make:rule) працюють так само, як у контролерах; - валідатор напряму:
$this->withValidator(fn ($validator) => $validator->after(...))- для перевірок, що охоплюють кілька полів.
Докладніше в документації: Валідація: правила в методі rules()