Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

earmsby's avatar

How to use mutateFormDataBeforeCreate when creating new record from RelationManager

I'm using a RelationManager to show a list of Contracts on the view for an Account.

The RelationManager allows a new contract to be created from the Account view using the form:

public function form(Schema $schema): Schema
    {
        return $schema
            ->components([
                TextInput::make('contract_number')
                    ->label('Contract ID')
                    ->default(Contract::getID())
                    ->required(),
                Select::make('contract_type')
                    ->required()
                    ->relationship('contractType',titleAttribute: 'contract_type_name')
                    ->preload()
                    ->createOptionForm(ContractType::getForm()),
                TextInput::make('contract_description')
                    ->columnSpanFull()
                    ->required(),
                Toggle::make('auto_renews')
                    ->label('Auto Renews')
                    ->default(false),
                Select::make('commit_status')
                    ->default('Draft')
                    ->options(CommitStatus::class)
            ]);
    }

When a new Contract is created NOT from the Account view but from the Contract panel itself, I'm using ("Resources/Contracts/Pages/CreateContract.php

protected function mutateFormDataBeforeCreate(array $data): array
    {
        //add the creator's user ID
        $data['added_by'] = auth()->id();

        return $data;
    }

To modify the data sent by the form and add an audit field that I don't want to show on the form.

When a new Contract is added from the form on the Account relation manager, this function doesn't run. So I'm guessing the create code is happening somewhere else. Where can I inject this extra data into the data used to create the new Contract record when doing so via a RelationshipManager?

0 likes
3 replies
LaryAI's avatar
Level 58

You're correct: when creating a related record via a Filament RelationManager, the mutateFormDataBeforeCreate method on your main resource's page (like CreateContract) is not called. Instead, RelationManagers have their own lifecycle hooks.

To mutate the form data before creating a record from a RelationManager, you should override the mutateFormDataBeforeCreate method on the RelationManager itself.

Here’s how you can do it:

use Filament\Resources\RelationManagers\RelationManager;

class ContractsRelationManager extends RelationManager
{
    // ... your existing code ...

    protected function mutateFormDataBeforeCreate(array $data): array
    {
        // Add the creator's user ID
        $data['added_by'] = auth()->id();

        return $data;
    }
}

Where to put this:

  • If your RelationManager is called ContractsRelationManager, add the method there.
  • This method will be called whenever a new Contract is created via the RelationManager (e.g., from the Account view).

Summary:

  • Use mutateFormDataBeforeCreate in your RelationManager class to mutate data before creation in that context.
  • Use it in your CreateContract page for standalone contract creation.

Reference:
Filament Docs: Relation Managers - Mutating Form Data

earmsby's avatar

Hmmm... that didn't seem to work. I added the code:

protected function mutateFormDataBeforeCreate(array $data): array
    {
        ray('We will add the user ID');
        //add the creator's user ID
        $data['added_by'] = auth()->id();

        return $data;
    }

directly to my file: ContractsRelationManager.php but it doesn't add the user ID and nothing hits Ray either, so it seems like this method doesn't run when the contract record is created. Wondering if there is another way to accomplish this.

earmsby's avatar

Ah, I figured it out. Instead of adding the method as shown in LarryAI's example, I added it to the "CreateAction" in the headerActions like so:

->headerActions([
                CreateAction::make()
                ->mutateDataUsing(function (array $data): array {
                    ray($data);
                    ray('We will add the user ID');
                    //add the creator's user ID
                    $data['added_by'] = auth()->id();
                    return $data;
                }),
                AttachAction::make()
                ->label('Link Existing Contract'),
            ])

And that did the trick.

Please or to participate in this conversation.