F
Filament15mo ago
MrHex

Image upload in relations

I Have a User model with a PersonalInfo relation:
class User extends Model
{
/**
* Get the user PI
*
* @return HasOne
*/
public function personalInfo(): HasOne
{
return $this->hasOne(PersonalInfo::class, 'user_id', 'id');
}
}
class User extends Model
{
/**
* Get the user PI
*
* @return HasOne
*/
public function personalInfo(): HasOne
{
return $this->hasOne(PersonalInfo::class, 'user_id', 'id');
}
}
in the PersonalInfo we have an avatar_id column that references to File model:
class PersonalInfo extends Model
{
/**
* The attributes that are mass assignable.
*
* @var string[]
*/
protected $fillable = [
'user_id',
'first_name',
'last_name',
'avatar_id', // here is the column
];

/**
* Get the avatar file
*
* @return BelongsTo
*/
public function avatar(): BelongsTo
{
return $this->belongsTo(File::class, 'avatar_id', 'id');
}
}
class PersonalInfo extends Model
{
/**
* The attributes that are mass assignable.
*
* @var string[]
*/
protected $fillable = [
'user_id',
'first_name',
'last_name',
'avatar_id', // here is the column
];

/**
* Get the avatar file
*
* @return BelongsTo
*/
public function avatar(): BelongsTo
{
return $this->belongsTo(File::class, 'avatar_id', 'id');
}
}
now i just made a PersonalInfoRelationManager to manage the relation from the UserResource and used the FileUpload form input like this:
FileUpload::make('avatar')
->image()
->demonLabel()
->columnSpan('full')
->saveUploadedFileUsing(
function ($file, callable $get, callable $set)
{
$dir = 'public/static/avatar/' . md5($get('id'));
$path = $file->storePublicly($dir);
$path = str_replace('public/static/', 'static/', $path);

$avatar = file_repo()->create(
[
'uploader_id' => auth()->id(),
'disk' => 'public',
'name' => $file->getClientOriginalName(),
'extension' => $file->getClientOriginalExtension(),
'path' => $path,
'alt' => '',
],
);

$set('avatar_id', $avatar->id);
},
)
->reactive()
FileUpload::make('avatar')
->image()
->demonLabel()
->columnSpan('full')
->saveUploadedFileUsing(
function ($file, callable $get, callable $set)
{
$dir = 'public/static/avatar/' . md5($get('id'));
$path = $file->storePublicly($dir);
$path = str_replace('public/static/', 'static/', $path);

$avatar = file_repo()->create(
[
'uploader_id' => auth()->id(),
'disk' => 'public',
'name' => $file->getClientOriginalName(),
'extension' => $file->getClientOriginalExtension(),
'path' => $path,
'alt' => '',
],
);

$set('avatar_id', $avatar->id);
},
)
->reactive()
the upload process is fine but when i re-open to modal, image doesn't shown to me... 😦 How can I fix this issue?
21 Replies
MrHex
MrHex15mo ago
I just used this code in the TableSchema and its correctly show the Image
ImageColumn::make('avatar.path')
->demonLabel('avatar')
->circular()
ImageColumn::make('avatar.path')
->demonLabel('avatar')
->circular()
But the image is not load in the modal or forms after re-opening them ... 😦
Dan Harrin
Dan Harrin15mo ago
relation managers are not built for hasone the docs state that they are used on multiple relationships like hasmany and belongstomany
Dan Harrin
Dan Harrin15mo ago
you shouldnt use a relation manager, you can just wrap any related fields inside a layout component - https://filamentphp.com/docs/2.x/forms/layout#saving-data-to-relationships
Filament
Layout - Form Builder - Filament
The elegant TALL stack form builder for Laravel artisans.
Dan Harrin
Dan Harrin15mo ago
then the files will be uploaded from the user form into the personal data a separate avatar relationship is absolutely overkill
MrHex
MrHex15mo ago
@danharrin it should not upload into the PersonalInfo relation. it should upload into the File relation that is related to the PersonalInfo
Dan Harrin
Dan Harrin15mo ago
why not just use media library and make your life easy? to store an ID instead of a path you need to copy what we did for media library which does something similar
MrHex
MrHex15mo ago
which media library you mean? Spatie? its an old project and refactoring may take a long time. what do u think?
Dan Harrin
Dan Harrin15mo ago
you dont have to use it for the whole project introduce it gradually im just saying that an avatar relationship is 100% an overkill that you will regret. just store the file name, or use media library
MrHex
MrHex15mo ago
ofc. ill refactor it right now
MrHex
MrHex15mo ago
Dan Harrin
Dan Harrin15mo ago
yeh or just store the path which is much easier
MrHex
MrHex15mo ago
we need to track the user uploads and report them in some cases admin may changes some attributes of the uploaded File in some cases and it MUST apply to the all places that we used the file so we NEED TO store it in a separated table like files and use the id via the relations... any idea to make this flow easier?
Dan Harrin
Dan Harrin15mo ago
the file is only ever associated with 1 model, right?
MrHex
MrHex15mo ago
no, it can be assigned to multiple models for e.g. we upload a foo.png so we have it with id 1 in the files table so whenever we want to use the foo.png we just need to open a modal and let the user to select between the uploaded files that is also contains the foo.png in it.
Dan Harrin
Dan Harrin15mo ago
Filament
Curator by Adam Weston - Plugins - Filament
A media picker field and media manager for Filament Admin.
Dan Harrin
Dan Harrin15mo ago
full media library that allows you to attach already uploaded files
MrHex
MrHex15mo ago
thanks for your time i have one other question, can i set a default path for the FileUpload field to previewing it?
Dan Harrin
Dan Harrin15mo ago
i dont know what you mean
MrHex
MrHex15mo ago
i just want to set a default image path for a FileUpload field that it used to preview the image by default
Dan Harrin
Dan Harrin15mo ago
you can pass ->default() but otherwise no
MrHex
MrHex15mo ago
it doesn't work, dont know why actually
Want results from more Discord servers?
Add your server
More Posts