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

kokoshneta's avatar

Filament: Save data from base model in layout component with defined relationship

When building Filament forms, you can use layout components to logically and visually group fields. Some layout components have a relationship() method that allows you to define that the data in this component belongs to a relationship, not to the base model.

For example, if you’re building a page to edit users and you have the user’s address in a separate table, you could add this inside the schema definition in your user resource’s form() method:

Section::make('Address')
	->relationship('address')
	->schema([
		TextInput::make('street'),
		TextInput::make('zip'),
		TextInput::make('state'),
		TextInput::make('country'),
		TextInput::make('phone'),
	])

That will make sure that clicking the “Save” button at the bottom of the page will also update the appropriate row in the addresses  table.

But what do you do when you have a section that doesn’t just have data belonging to the relationship, but also to the base model itself? For example, say the user’s phone number is actually stored directly in the users table, and not in the addresses table. In that case, the phone field on the page will be empty, because Filament is looking for $user->address->phone instead of $user->phone. Saving the form will then obviously also not update the phone number.

(This is a stupid example, of course – saving an address in a separate table, but a phone number in the main table would be idiotic. The principle still applies, though, that sometimes the way data is arranged in the database isn’t the most intuitive way to present it to an admin editing the resource.)

Is there a way to tell Filament that a particular field does not belong to the relationship defined for the layout component, but should be scoped to the parent model?

0 likes
4 replies
LaryAI's avatar
Level 58

Yes, you can use the scopeTo method to tell Filament that a particular field should be scoped to the parent model. Here's an example:

Section::make('Contact Information')
    ->relationship('contact')
    ->schema([
        TextInput::make('name'),
        TextInput::make('email'),
        TextInput::make('phone')->scopeTo('user'),
    ])

In this example, the phone field is scoped to the user model, so it will look for $user->phone instead of $user->contact->phone. This will allow you to save the phone number to the users table instead of the contacts table.

kokoshneta's avatar

Damn, Lary got my hopes all up there!

Unfortunately there is no scopeTo() method anywhere in Filament, so this won’t work.

cseidl1's avatar
cseidl1
Best Answer
Level 3

@kokoshneta You can use a Group component, which has no styling associated with it. Following instructions from the "saving data to relations" section in Filament PHP's documentation (I can't link to it because I just signed up), you could make something like this, for example:

Forms\Components\Section::make('Status details')
    ->schema([
        Group::make()
            ->relationship('meta')
            ->schema([
                Forms\Components\TextInput::make('title')
                    ->label('Title')
                    ->live(onBlur: true)
                    ->afterStateUpdated(fn (Set $set, ?string $state) => $set('slug', Str::slug($state)))
                    ->required()
                    ->maxLength(255),
                Forms\Components\RichEditor::make('description')
                    ->label('Description')
                    ->required(),
                Forms\Components\Hidden::make('slug'),
                Forms\Components\Hidden::make('meta_type')->default('main'),
            ]),
        Forms\Components\Select::make('model')
            ->label('Model')
            ->required()
            ->native(false)
            ->options(
                'key1' => 'Option 1',
                'key2' => 'Option 2',
                // etc.
            ),
    ]),

All of the form elements appear together in the same section, "Status details."

kokoshneta's avatar

@cseidl1 I think that’s actually more or less what I ended up doing in the situation I was facing back when I asked. I don’t remember exactly what the actual model/data I was having trouble with was, but I know I did get it fixed.

The only trouble with this approach is that it requires having the base-model data separate from the relationship-model data; that is, in your example, you can only display it as either Model, [Title, Description] or [Title, Description], Model – there’s no way to make it Title, Model, Description.

I think I just accepted that as a limitation I couldn’t do anything about.

Please or to participate in this conversation.