F
Filament2mo ago
Nicole

User Profile

Hello, I currently have a user and profile model. What I want to achieve is that when I create or update a user, there should be a profile form below it. This way, when I save the user data, I also want the profile to be automatically filled.
No description
Solution:
Or easy way.. you can do like this and remove "additional logic" ```php Forms\Components\Section::make() ->relationship('profile') ->schema([...
Jump to solution
9 Replies
Expecto Patronum
What relationship are you using for both model ? Probably you can apply by using fieldset or relation manager
Nicole
Nicole2mo ago
One to one relationship Like user hasOne profile
Vp
Vp2mo ago
// User model
public function profile(): HasOne
{
return $this->hasOne(Profile::class);
}

// User form (resources)
Forms\Components\TextInput::make('profile.age'),
Forms\Components\TextInput::make('profile.height'),
// User model
public function profile(): HasOne
{
return $this->hasOne(Profile::class);
}

// User form (resources)
Forms\Components\TextInput::make('profile.age'),
Forms\Components\TextInput::make('profile.height'),
Nicole
Nicole2mo ago
Yes I did that but is not automatically saving to database table profile Techinically I still need to update the createUser class
<?php

namespace App\Filament\Resources\Main\UserResource\Pages;

use App\Filament\Resources\Main\UserResource;
use Filament\Resources\Pages\CreateRecord;
use Illuminate\Database\Eloquent\Model;

class CreateUser extends CreateRecord
{
protected static string $resource = UserResource::class;

protected function handleRecordCreation(array $data): Model
{
$record = static::getModel()::create($data);

$record->profile()->create(array_merge(['user_id' => $record->id], $data['profile']));

return $record;
}
}
<?php

namespace App\Filament\Resources\Main\UserResource\Pages;

use App\Filament\Resources\Main\UserResource;
use Filament\Resources\Pages\CreateRecord;
use Illuminate\Database\Eloquent\Model;

class CreateUser extends CreateRecord
{
protected static string $resource = UserResource::class;

protected function handleRecordCreation(array $data): Model
{
$record = static::getModel()::create($data);

$record->profile()->create(array_merge(['user_id' => $record->id], $data['profile']));

return $record;
}
}
Nicole
Nicole2mo ago
My issue now is I want to display the profile data if it is "edit" page and null if "create" page
No description
Vp
Vp2mo ago
You can customize like this
// create pages
protected function afterCreate(): void
{
$this->record->profile()->create($this->data['profile']);
}

// edit pages
protected function mutateFormDataBeforeFill(array $data): array
{
$data['profile']['age'] = $this->record->profile?->age;
$data['profile']['height'] = $this->record->profile?->height;

return $data;
}

protected function afterSave(): void
{
$this->record->profile()->update($this->data['profile']);
}
// create pages
protected function afterCreate(): void
{
$this->record->profile()->create($this->data['profile']);
}

// edit pages
protected function mutateFormDataBeforeFill(array $data): array
{
$data['profile']['age'] = $this->record->profile?->age;
$data['profile']['height'] = $this->record->profile?->height;

return $data;
}

protected function afterSave(): void
{
$this->record->profile()->update($this->data['profile']);
}
Nicole
Nicole2mo ago
Thank you!
Solution
Vp
Vp2mo ago
Or easy way.. you can do like this and remove "additional logic"
Forms\Components\Section::make()
->relationship('profile')
->schema([
Forms\Components\TextInput::make('age'),
Forms\Components\TextInput::make('height'),
])
Forms\Components\Section::make()
->relationship('profile')
->schema([
Forms\Components\TextInput::make('age'),
Forms\Components\TextInput::make('height'),
])
If you use like this, then you can remove all of this additional inside 'create' and 'edit' pages
Nicole
Nicole2mo ago
Thank you I'll try Seems working, ty!