customize creating related model in Select form component when using createOptionForm()

Hi I have a Select form component that is connected with relationship named 'partner' and I want to enable users to create a partner from Select component by using ->createOptionForm() method. My Partner model has many-to-many relationship to PartnerType model and I want set that relationship when creating new Partner, but I do not want the user is able to select partner type. I want to assign fixed partner type when new partner is created. What would be the best way to achieve that? I've tried something like this, but Filament said that ComponentAction doesn't have using() method:
Forms\Components\Select::make('partner_id')
->relationship(name: 'partner')
->createOptionForm([...])
->createOptionAction(fn (Forms\Components\Actions\Action $action) =>
$action
->label('New partner')
->using(function (array $data, Partner $model) {
return $model::create($data)->types()->attach(
PartnerType::query()
->where('is_client', 1)
->first()?->id
??
null
);
})
)
Forms\Components\Select::make('partner_id')
->relationship(name: 'partner')
->createOptionForm([...])
->createOptionAction(fn (Forms\Components\Actions\Action $action) =>
$action
->label('New partner')
->using(function (array $data, Partner $model) {
return $model::create($data)->types()->attach(
PartnerType::query()
->where('is_client', 1)
->first()?->id
??
null
);
})
)
2 Replies
Tieme
Tieme5mo ago
tjodalv
tjodalv5mo ago
The thing is that I do not want to change Partner form data, but I would like to assign relationship on newly created Partner model. That is the reason I tried to use using() method. But that method is not available on Filament\Forms\Components\Actions\Action class. I didn't find a proper way to update my model after being created through Select component but I've managed to achieve what I wanted by using method afterStateUpdated() on Select form component and then checking if my Partner doesn't have assigned any type then assign the type that I want to be assigned. See an example:
Forms\Components\Select::make('partner_id')
->relationship(name: 'partner')
->createOptionForm([...])
->afterStateUpdated(function ($state, $set) {
$partnerId = (int) $state;
if ($partnerId === 0) return;

$partner = Partner::find($partnerId);
if (! $partner) return;

// If partner doesn't have a type defined the set type to client
if ($partner->types->count() === 0) {
$partner->types()->attach(
PartnerType::query()
->where('is_client', 1)
->orderBy('default_type', 'desc')
->first()?->id
??
null
);
}
})
Forms\Components\Select::make('partner_id')
->relationship(name: 'partner')
->createOptionForm([...])
->afterStateUpdated(function ($state, $set) {
$partnerId = (int) $state;
if ($partnerId === 0) return;

$partner = Partner::find($partnerId);
if (! $partner) return;

// If partner doesn't have a type defined the set type to client
if ($partner->types->count() === 0) {
$partner->types()->attach(
PartnerType::query()
->where('is_client', 1)
->orderBy('default_type', 'desc')
->first()?->id
??
null
);
}
})