Use resource record ID in file upload path

I need to use the record id in my file path when uploading files. Is this possible, and if so, how would I go about doing that? This is my form:
Section::make()
->description('Attach any files related to this policy')
->heading('Claim attachments')
->schema([
FileUpload::make('attachments')
->label('')
->multiple()
->disk('public')
->directory('claim-attachments')
->preserveFilenames()
->downloadable()
->enableOpen()
->previewable(false)
]),
Section::make()
->description('Attach any files related to this policy')
->heading('Claim attachments')
->schema([
FileUpload::make('attachments')
->label('')
->multiple()
->disk('public')
->directory('claim-attachments')
->preserveFilenames()
->downloadable()
->enableOpen()
->previewable(false)
]),
I would like to use something like, ->directory('claim-attachments' . $this->id)
4 Replies
Matthew
Matthew5mo ago
Not sure if thats possible, since when you are uploading and you are creating a record, and thus since its not yet created it will be null
Wayne_Swart
Wayne_Swart5mo ago
There is a mutateFormDataBeforeCreate() method you can call in the create page, but the attachments seem to be empty in the posted array, since they are uploaded in realtime. So I could get it to work on the edit page, but not during create. A workaround could potentially be to hide the file attachments during creation and only show it on the edit page. Is something like that possible? As amazing as filament is, I feel there are a lot of hacking needed in order to get basic things done unfortunately ;/ So, here is my solution using the mutateFormDataBeforeCreate() function when the form is submitted. It is based off of another user's code. It's not pretty, but it does work:
protected function mutateFormDataBeforeCreate(array $data): array
{
if (is_array($data['attachments'])) {

// Get the next auto increment from the database.
$nextAutoIncrement = Claim::getModel()::max('id') + 1;

foreach ($data['attachments'] as $key => $value) {
// Move the uploaded files from the temporary storage to the public storage.
Storage::disk('public')->move( $value, 'claim-attachments/' . $nextAutoIncrement . '/' . str_replace('claim-attachments/','', $value));

// Change the file path to be the next auto increment.
$data['attachments'][$key] = 'claim-attachments/' . $nextAutoIncrement . '/' . str_replace('claim-attachments/','', $value);
}
}
return $data;
}
protected function mutateFormDataBeforeCreate(array $data): array
{
if (is_array($data['attachments'])) {

// Get the next auto increment from the database.
$nextAutoIncrement = Claim::getModel()::max('id') + 1;

foreach ($data['attachments'] as $key => $value) {
// Move the uploaded files from the temporary storage to the public storage.
Storage::disk('public')->move( $value, 'claim-attachments/' . $nextAutoIncrement . '/' . str_replace('claim-attachments/','', $value));

// Change the file path to be the next auto increment.
$data['attachments'][$key] = 'claim-attachments/' . $nextAutoIncrement . '/' . str_replace('claim-attachments/','', $value);
}
}
return $data;
}
I am not yet going to mark this post as solved, since I would like to know if there isn't another easier way to do this. Thanks.
Matthew
Matthew5mo ago
Cant you just do this? ->directory(Claim::max('id') + 1) I think you are overcomplicating it
Wayne_Swart
Wayne_Swart5mo ago
That's a great idea, thanks. Let me see if I can use that way. Thank you! Wow, thank you Matthew. I was over complicating it, your solution does indeed work.