Filament provides a convenient way to deal with the relationship between two Modals, read more in the section “Attaching and detaching records” from the official document.
However, the ‘AttachAction’ and also ‘DetachAction’ are for ‘BelongsToMany’ and ‘MorphToMany’ relationships. They tried to grab the Pivot table during queries. Like:
$this->process(function (array $data) {
/** @var BelongsToMany $relationship */
$relationship = $this->getRelationship();
$record = $relationship->getRelated()->query()->find($data['recordId']);
$relationship->attach(
$record,
Arr::only($data, $relationship->getPivotColumns()),
);
});
For those ‘HasMany’ relationships, especially Many-to-One relationships, it can’t work magically.
To achieve that, we need to define an action() to overwrite the default action().
For example:
->headerActions([
Tables\Actions\CreateAction::make(),
Tables\Actions\AttachAction::make()
->label("Modified Attach")
->form(fn(Tables\Actions\AttachAction $action): array => [
$action->getRecordSelect(),
])->action(function (Tables\Actions\AttachAction $action, array $data): void {
// Overwrite the default action of AttachAction
$parent_id = $action->getRelationship()->getParent()->getKey();
$this_relationship_id = (isset($data['recordId'])) ? $data['recordId'] : null;
if ($parent_id and $this_relationship_id) {
$parent = ParentObj::where('id', $parent_id)->firstOrFail();
$parent->this_relationship_id = $this_relationship_id;
$parent->save();
}
}),
])
