Using a custom attribute that requires an API request for each user within a Filament table filter is indeed not an ideal solution due to the potential performance issues. However, if you must implement this, you could use a custom query callback for the filter to handle the logic.
Here's an example of how you might approach this:
SelectFilter::make('myCustomAttribute')
->options([
'with' => 'With',
'without' => 'Without',
])
->query(function ($query, $value) {
// Assuming you have a method on your User model that checks the custom attribute
// and that method is called `hasCustomAttribute` which returns a boolean.
$userIdsWithAttribute = [];
$userIdsWithoutAttribute = [];
// This is not efficient, but it's what the question asks for.
// It would be better to store the result of the API request in the database and query it.
foreach ($query->get() as $user) {
if ($user->hasCustomAttribute()) {
$userIdsWithAttribute[] = $user->id;
} else {
$userIdsWithoutAttribute[] = $user->id;
}
}
if ($value === 'with') {
$query->whereIn('id', $userIdsWithAttribute);
} else {
$query->whereIn('id', $userIdsWithoutAttribute);
}
});
Please note that this code will execute an API request for each user every time the filter is applied, which can be very slow and resource-intensive. It's highly recommended to cache the results of the API request or store them in the database to avoid making an API request for each user every time.
If you can modify the user model to include a cached version of the custom attribute, you could then use a standard query filter without the performance penalty. Here's an example of how you might do that:
// In your User model, add a method to update the custom attribute
public function updateCustomAttribute()
{
// Perform the API request and store the result in a column like `has_custom_attribute`
$this->has_custom_attribute = $this->fetchCustomAttributeFromApi();
$this->save();
}
// Then, in your Filament filter, you can simply query the database column
SelectFilter::make('myCustomAttribute')
->options([
'with' => 'With',
'without' => 'Without',
])
->query(function ($query, $value) {
if ($value === 'with') {
$query->where('has_custom_attribute', true);
} else {
$query->where('has_custom_attribute', false);
}
});
This second approach assumes that you have a boolean column has_custom_attribute in your users table that stores the result of the API request. You would need to ensure that this column is updated regularly to reflect the current state of the custom attribute.