Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як у Livewire валідувати масиви, умовні правила й унікальність з виключенням поточного запису?

Коли правила залежать від стану компонента чи потребують об'єктів правил 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()

Схожі питання