Skip to main content
Tutorial Free

Filament 3 Multi-Tenancy: Validation - Unique Value Per Tenant

September 01, 2023
2 min read

Filament 3 has a multi-tenancy feature. In this tutorial, let's make a validation rule with a unique field value for the current tenant. As with everything with Laravel, there is more than one way to do it, so we will see how to achieve it in three ways.

In this example, our tenant is a Company Model and is set in the Panel Provider:

app/Providers/Filament/AdminPanelProvider.php:

use App\Models\Company;
 
class AdminPanelProvider extends PanelProvider
{
public function panel(Panel $panel): Panel
{
return $panel
->default()
->tenant(Company::class)
// ...
}
}

The Filament Resource is a CategoryResource with just one name field, which needs to be unique just for an active tenant.

unique column per tenant


Method 1. Filament Custom Callback

For the first method, we will use a custom validation rule and pass a closure to it.

Forms\Components\TextInput::make('name')
->rules([
function () {
return function (string $attribute, $value, Closure $fail) {
if (filament()->getTenant()->categories->contains('name', $value)) {
$fail('The :attribute must be unique per tenant.');
}
};
}
])
->required()
->maxLength(255),

In this callback, we check if, in the tenants categories relation, there is a $value in the name DB field. If the check is true, we show the validation error.


Method 2. Laravel Validation Rule::unique()

For the second method, we will use a Laravel validation rule unique, which needs to be added to the rules method.

use Illuminate\Validation\Rule;
 
Forms\Components\TextInput::make('name')
->rules(Rule::unique('categories', 'name')->where('company_id', filament()->getTenant()->id))
->required()
->maxLength(255),

For the Rule, we are setting the relation name and field name and adding where to check the current tenant.


Method 3. Filament unique()

The last third method will use the Filament unique rule.

Forms\Components\TextInput::make('name')
->unique('categories', 'name', null, 'id', function($rule){
return $rule->where('company_id', filament()->getTenant()->id);
})
->required()
->maxLength(255),

Similar to the second method, we set the relation name with the field name and add where to check the current tenant.

So, which method do you prefer?


If you want more Filament examples, you can find more real-life projects on our FilamentExamples.com.

Enjoyed This Tutorial?

Get access to all premium tutorials, video and text courses, and exclusive Laravel resources. Join our community of 10,000+ developers.

Comments & Discussion

ME
MOHAMED ESSAKILI ✓ Link copied!

Another way for doing it if using simple tenancy: Forms\Components\TextInput::make('invoice_number') ->label(Invoice Number') ->required() ->unique( 'orders', 'invoice_number', ignoreRecord: true, modifyRuleUsing: fn($rule) => $rule->where('team_id', auth()->user()>team_id) ),

We'd Love Your Feedback

Tell us what you like or what we can improve

Feel free to share anything you like or dislike about this page or the platform in general.