laravellaravel-filamentfilamentphp

Laravel Filament Relationship Title Attribute


When displaying the form for a model and it's select relationship, I want to customize the title attribute it displays in the selection. Specifically, I want to have the user title come back as 'first_name last_name'.

This is standard:

public static function form(Form $form): Form
    {
        return $form
            ->schema([
                Select::make('user_id')
                    ->relationship('user', 'first_name')
                    ->required(),
                TextInput::make('name')
                    ->required()
                    ->maxLength(255),
            ]);
    }

and it returns something like this enter image description here but I want first and last name, not just first name.

I did see Laravel - Filament: get distinct values of a relationship column which made me think I could do some kind of query, like

->relationship('user', 'first_name', function(Builder $query) {
                        $query->select('id', 'first_name', 'last_name', 'email');

but nothing seems to work because you still call the column in the 2nd argument to query... I can do a query and where, and it will filter by the where clause...

In Laravel nova, you can easily do this https://nova.laravel.com/docs/resources/relationships.html#title-attributes-1

public static $title = 'name';
/**
 * Get the value that should be displayed to represent the resource.
 *
 * @return string
 */
public function title()
{
    return $this->first_name . ' ' . $this->last_name;
}

However, in filament, it doesn't seem like this is possible. I did see https://filamentphp.com/docs/3.x/panels/resources/relation-managers, but that seems to only work on the relation manager page.

Since this 2nd argument is suppose to be a column name, it was suggested to create a virtual column like this:

$table->string('full_name')->virtualAs('concat(first_name, \' \', last_name)');

Is this really the only way?


Solution

  • You can use the getOptionLabelFromRecordUsing() method to transform an option's Eloquent model into a label

    ->getOptionLabelFromRecordUsing(fn (Model $record) => "{$record->first_name} {$record->last_name}")
    

    Docs: https://filamentphp.com/docs/3.x/forms/fields/select#customizing-the-relationship-option-labels