Tricks

Get $ownerRecord in RM's Table Actions While Using Preset Actions

Jun 21, 2022
Joni Chandra
Admin panel

Since v2.13.0 Filament has added a bunch of new Action classes (e.g CreateAction, EditAction, etc) which allow developers to reduce code repetitions especially in their Resources and RelationManagers and today, I would like to share with you a trick which allow Action classes to access a RelationManager's $ownerRecord.

Filament heavily uses EvaluatesClosure trait which allows classes to resolve dependencies by delegating it to the service container and in my use case, I would like add an authorization Closure into CreateAction's hidden() which requires the $ownerRecord but it is unavailable by default in Filament.

Below is a snippet of getDefaultEvaluationParameters() in the default Action class

namespace Filament\Tables\Actions;
 
// ...
 
protected function getDefaultEvaluationParameters(): array
{
return array_merge(parent::getDefaultEvaluationParameters(), [
'record' => $this->resolveEvaluationParameter(
'record',
fn (): ?Model => $this->getRecord(),
),
]);
}
 
// ...

As seen in the snippet above, Filament only provides the $record parameter which allows developers to write Closure that like the one below.

 
namespace Your\Custom\Namespace\Actions;
 
use Filament\Tables\Actions\EditAction as BaseEditAction;
 
class EditAction extends BaseEditAction
{
protected function setUp(): void
{
parent::setUp();
 
// $record will contain the database entry for the model
$this->hidden(function (Model $record) {
// dump($record);
})
}
}

In order to get the $ownerRecord to be accessible in the custom Action classes, we simply have to override getDefaultEvaluationParameters() in our custom Action class and add the parameters ourselves.

 
namespace Your\Custom\Namespace\Actions;
 
use Filament\Tables\Actions\CreateAction as BaseCreateAction;
 
class CreateAction extends BaseCreateAction
{
protected function setUp(): void
{
parent::setUp();
 
// $record will be null, since this is a `CreateAction`
// $ownerRecord will contain the database entry of the owner
$this->hidden(function (Model $record, Model $ownerRecord) {
// dump($record, $ownerRecord);
})
}
 
protected function getDefaultEvaluationParameters(): array
{
return array_merge(parent::getDefaultEvaluationParameters(), [
'ownerRecord' => $this->resolveEvaluationParameter(
'ownerRecord',
fn (): ?Model => $this->getRelationship()->getParent(),
),
]);
}
}

That's it!

I hope this trick has been helpful to you as it has been for me as I'm still trying to explore and learn about Filament's internals and I would like to thank the creator(s) of Filament for creating such valuable tools that allows us developers to be productive in our work. Last but not least, thank you for your time and stay healthy. See you in the next trick!

No comments yet…