F
Filament11mo ago
KeyMe

Relationship record not automatically created in resource View page action

I have an Order model with relationship of hasOne Training model. After order creation, there is an action modal in the ViewOrder page that prompt user to enter remarks. Upon action submission, I was hoping a related Training record would be created if not existed yet, else its remarks field should be updated but alas only updating existing record works. I've simplified the code below for review purpose.
Action::make('requestReviseOrder')
->form([
TextArea::make('remarks')
])
->action(function (array $data): void {
$this->record->training()- >update($data);
$this->fillForm();
}
Action::make('requestReviseOrder')
->form([
TextArea::make('remarks')
])
->action(function (array $data): void {
$this->record->training()- >update($data);
$this->fillForm();
}
Order class
public function training(): HasOne
{
return $this->hasOne(Training::class);
}
public function training(): HasOne
{
return $this->hasOne(Training::class);
}
Training class
public function order(): BelongsTo
{
return $this->belongsTo(Order::class);
}
public function order(): BelongsTo
{
return $this->belongsTo(Order::class);
}
4 Replies
Patrick Boivin
Patrick Boivin11mo ago
Are there any fields from Training embedded in the Order form? If not, there's nothing signaling Filament to create the related item. One option would be to create it manually in a model observer or in a lifecycle hook like afterCreate(): https://filamentphp.com/docs/3.x/panels/resources/creating-records#lifecycle-hooks
Patrick Boivin
Patrick Boivin11mo ago
Or maybe directly in the ->action()? You could check if the related item exists before trying to update it.
KeyMe
KeyMe11mo ago
Okay, I tried doing it like this, but no result
->action(function (array $data): void {
$training = $this->record->training();
($training) ?
$training->update($data) :
$this->record->training()->create(['remarks' => $data['remarks']]);
->action(function (array $data): void {
$training = $this->record->training();
($training) ?
$training->update($data) :
$this->record->training()->create(['remarks' => $data['remarks']]);
oh i checked the wrong thing, should be $training->exists(). You think my method is gud enough? or is it better to just auto create related records in orderObserver created event
Patrick Boivin
Patrick Boivin11mo ago
Yes, I think I would do it this way personally, with action()... model observers are powerful but more complicated to keep track of.