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

kszyrvercobrador's avatar

Filament(v3) Forms for multiple relationship but same model

I have a Customer model that look like this

class Customer extends Model
{
    public function residentialAddress(): HasOne
    {
        return $this->hasOne(Address::class)->where('type', 'residential');
    }

   public function businessAddress(): HasOne
   {
        return $this->hasOne(Address::class)->where('type', 'business');
    }
}

Is there a way I can name the field on Filament form with the relationship name ? For example:

TextInput::make('residentialAddress.city');
TextInput::make('businessAddress.city');

This is the form Form

0 likes
5 replies
jaseofspades88's avatar

I do a similar thing on filament with polymorphic addresses, which works when using TextColumn::make('mainAddress.city'); but it appears you are trying to edit via a relationship here?

I would suggest you create an AddressRelationManager for your CustomerResource. This way you can manage both addresses (and their respective types) on the view and edit pages of the CustomerResource.

kszyrvercobrador's avatar

@jaseofspades88 Yes it will work when displaying it to table using TextColumn::make('residentialAddress.city') but won't work on create and edit. Im not sure if RelationshipManager can implement this. This is what my form looks like Form

jaseofspades88's avatar

Relation managers are used for managing related models on a resource, that's what they're for. @kszyrvercobrador. You will have to override the creation process to achieve this. So, as it stands all your resource fields map to the model fields. But if you added for example a field called TextInput::make('city'); then what you would need to do is intercept the creation process where you'd be able to hook in to the relationship and create.

Go to your CreateCustomer component (via CustomerResource) and override the following function and do something like this...

    protected function handleRecordCreation(array $data): Model
    {
			$data = Arr::except($data, 'city'); //exclude all of the custom fields you don't wish to try and persist to customer

			$customer = parent::handleRecordCreation($data); // create the customer using the filament create

			$customer-> residentialAddress()->create(Arr::only($data, ['city', 'postcode', 'etc'])); //create the address from the newly created customer relationship, passing desired variables from $data.

			return $customer;
    }

I hope this helps...

kszyrvercobrador's avatar

@jaseofspades88 based on Filament docs, RelationManager only works with HasMany, HasManyThrough, BelongsToMany, MorphMany and MorphToMany relationships.

I do make it work by adding prefix on my field name

Select::make('residential_city_id')
Select::make('business_city_id')

Then mutating the data before create/save/fill

$section->mutateRelationshipDataBeforeCreateUsing($callback)
$section->mutateRelationshipDataBeforeSaveUsing($callback)
$section->mutateRelationshipDataBeforeFillUsing($callback)

Please or to participate in this conversation.