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
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');
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?
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