Replicate action with custom after logic

I'm trying to add some additional logic to also sync relationships to the replicated model and not only the model itself. And due to a complex relationship setup I also need to do the replicate the model without events.
class ReplicateReportAction
{
public static function make(): ReplicateAction
{
return ReplicateAction::make()
->mutateRecordDataUsing(fn (array $data): array => [...$data, 'name' => sprintf('%s copy', $data['name'])])
->modalDescription(fn () => __('actions.replicate_action.report_modal_description'))
->modalHeading(fn () => __('actions.replicate_action.report_modal_title'))
->using(fn (Report $record) => $record->replicate()->saveQuietly())
->after(function (Report $record, Report $replica) {
// Custom logic that uses the replica id of the new model
});
}
}
class ReplicateReportAction
{
public static function make(): ReplicateAction
{
return ReplicateAction::make()
->mutateRecordDataUsing(fn (array $data): array => [...$data, 'name' => sprintf('%s copy', $data['name'])])
->modalDescription(fn () => __('actions.replicate_action.report_modal_description'))
->modalHeading(fn () => __('actions.replicate_action.report_modal_title'))
->using(fn (Report $record) => $record->replicate()->saveQuietly())
->after(function (Report $record, Report $replica) {
// Custom logic that uses the replica id of the new model
});
}
}
But when using this action Argument #2 ($replica) must be of type App\Models\Report, null given is thrown.
2 Replies
Amelia
Amelia•2mo ago
The error you're encountering—Argument #2 ($replica) must be of type App\Models\Report, null given—typically occurs because the ReplicateAction’s after callback isn't getting the new model as expected, likely due to changes in Filament or how the method is used. The new model ends up as null because Filament (or your code) isn't properly handling/save/return the replica in this context, especially when you replicate "without events" and try to add relationship syncing. Use the Filament-specific lifecycle hook beforeReplicaSaved instead of relying on the after callback. This ensures proper access to the replica before it’s saved, allowing you to mutate data, sync relationships, or handle complex logic reliably. "ReplicateAction::make() ->mutateRecordDataUsing(fn (array $data): array => [...$data, 'name' => sprintf('%s copy', $data['name'])]) ->modalDescription(fn () => ('actions.replicate_action.report_modal_description')) ->modalHeading(fn () => ('actions.replicate_action.report_modal_title')) ->beforeReplicaSaved(function (Report $replica, Report $record) { // Custom logic: use $replica's id, sync relationships, etc. // Example: $replica->someRelated()->sync($record->someRelated()->pluck('id')); });"
Mike 🚀
Mike 🚀OP•2mo ago
The thing is that at that point the replica does net yet have a id so for hasMany relationships this is not possible unless I misunderstood something

Did you find this page helpful?