Laravel Filament: unique validation in relation manager over parent record values

(The following applies for Filament 2.x.)

Sometimes you need unique validation in relation managers, but only for models that are attached to the same parent record. Let’s take selling various chocolate bars as an example. Assuming you have a product named “Snickers” with multiple sizes, such as “small” or “large”, you’ll probably want the size variation name (e.g. “small”) to be unique – but only in the context of the same parent (e.g. “Snickers”). You’ll want other products (e.g. “Twix”) to be able to have the same variation name as well (so you could have both a small Twix and a small Snickers).

To do that, you’ll need to implement a custom callback for the field’s unique() function which ensures that there’s no variant with the given name and parent record ID. Getting the parent record ID is the non-obvious part: you’ll need to access the Livewire component of the relation manager to get its owner record ID.

use Filament\Resources\RelationManagers\RelationManager;
use Filament\Resources\Form;
use Livewire\Component as LivewireComponent;

class ProductVariantRelationManager extends RelationManager {

    public static function form(Form $form): Form
    {
        return $form->schema([
            TextInput::make('name')
                ->unique(callback: function (Unique $rule, callable $get, LivewireComponent $livewire) {
                    return $rule->where(function (Builder $query) use ($get, $livewire) {
                        return !$query
                            ->where('name', $get('name'))
                            ->where('product_id', $livewire->ownerRecord?->id)
                            ->count();
                    });
                }, ignoreRecord: true),
        ]);
    }
}

Leave a Reply

Your email address will not be published. Required fields are marked *