F
Filament2mo ago
bouly

Backend validation when using ModifyQueryUsing

Hello, I notice that when using ModifyQueryUsing on a field, there is no validation of the value sent by the client in the backend. Is this possible?
Select::make('roles')
->label(__('Role'))
->relationship(
name: 'roles',
titleAttribute: 'name',
modifyQueryUsing: fn(Builder $query) => auth()->user()->hasRole('super_admin') ? $query : $query->whereNot('name', 'super_admin'),
)
->preload()
->required()
->searchable(),
Select::make('roles')
->label(__('Role'))
->relationship(
name: 'roles',
titleAttribute: 'name',
modifyQueryUsing: fn(Builder $query) => auth()->user()->hasRole('super_admin') ? $query : $query->whereNot('name', 'super_admin'),
)
->preload()
->required()
->searchable(),
Step to reproduce : 1. Comment the modifyQueryUsing line. 2. Load the page and select "super_admin" 3. Uncomment the line. 4. Send the form Am I wrong?
Solution:
Ok my bad. I misunderstood... Here is the solution : ```php // In App\Models\User.php public function viewableRoles(): BelongsToMany...
Jump to solution
11 Replies
LeandroFerreira
LeandroFerreira2mo ago
looks ok here
Select::make('categories')
->relationship(
name: 'categories',
titleAttribute: 'name',
modifyQueryUsing: function ($query) {
$query->orderBy('name');
})
->required()
->minItems(3)
->multiple()
->preload()
->searchable(),
Select::make('categories')
->relationship(
name: 'categories',
titleAttribute: 'name',
modifyQueryUsing: function ($query) {
$query->orderBy('name');
})
->required()
->minItems(3)
->multiple()
->preload()
->searchable(),
No description
bouly
boulyOP2mo ago
Thanks for your reply. But I meant validation of the data returned by the modified query. If I modify your query to only return categories 1 and 2, how can I ensure that the user do not force it to choose category 3? Most of the time I work with global scopes based on roles, but here I can't technically do that.
TDDeveloper
TDDeveloper2mo ago
Hi @bouly Are you not looking for authorization with policies?
toeknee
toeknee2mo ago
You would tend to add it to the query in the relationship for that level? But you can add a custom validation that ensures again if you really want... but the current user should never be able to select a different level as per the policies setup
bouly
boulyOP2mo ago
I use global scopes whenever possible in my code. Unfortunately, here I am using the filament-shield plugin and I don't think I can define a different scope. So I am looking for a way to filter the list on both front and backend.
toeknee
toeknee2mo ago
You can use the default scopes and add custom scopes where needed? So a simple relationship on the model will apply the scope anyway on boot
bouly
boulyOP2mo ago
Do you know how to do that with this plugin? I did not find anything about scoping in the documentation
toeknee
toeknee2mo ago
It’s just standard laravel, in the relationship just add the additional where query?
bouly
boulyOP2mo ago
Ok, but I don't want to list the user roles. I want to list all roles (so that I can assign them, EXCEPT the super_admin role). So I don't understand why working with a relationship.
toeknee
toeknee2mo ago
Isn’t this for assigning roles to a user? Except admin roll?
Solution
bouly
bouly2mo ago
Ok my bad. I misunderstood... Here is the solution :
// In App\Models\User.php
public function viewableRoles(): BelongsToMany
{
if (Auth::user()->isSuperAdmin()) {
return $this->roles();
}
return $this->roles()->where('name', '!=', config('filament-shield.super_admin.name'));
}

// In the form
->relationship(
name: 'viewableRoles',
titleAttribute: 'name',
)
// In App\Models\User.php
public function viewableRoles(): BelongsToMany
{
if (Auth::user()->isSuperAdmin()) {
return $this->roles();
}
return $this->roles()->where('name', '!=', config('filament-shield.super_admin.name'));
}

// In the form
->relationship(
name: 'viewableRoles',
titleAttribute: 'name',
)
Thanks!

Did you find this page helpful?