christogonus's avatar

Update multiple models that include file upload

I have an edit page that allows user to change content on multiple instances of a model at same time.

Model Post. Attributes: title, body.

When you select to edit 3 posts, the forms show for the 3 models using a loop with key like

@foreach($posts as $key => $post)

<div wire:key="{{ $key }}">

		<h1> Post {{ $key }} </h1>

		<label>Title: <input wire:model.defer="posts.{{ $key }}.title" required /></label>

		<label>Body: <textarea wire:model.defer="posts.{{ $key }}.body" required ></textarea></label>

</div>

@endforeach

<button type="button"  wire:click="savePosts">Update Posts</button>

And the action "savePosts"

public function savePosts() {
	$this->posts->each(function ($post) {
		$post->save()
	});
}

now, I wish to add a column for image upload and allow images to up uploaded to existing posts that had no featured image.

At the early stage, I avoided using a nested livewire component for the edit to ensure that server requests are kept at minimal when updating multiple posts.

But I do not seem to know how to handle file upload in-between.

Help me figure this out.

Thanls.

0 likes
1 reply
LaryAI's avatar
LaryAI
AI
Best Answer
Level 58

To handle file uploads in your scenario, you can make use of Livewire's file upload capabilities. Here's how you can modify your code to include file uploads for each post:

  1. Update your view code to include a file input field for each post:
@foreach($posts as $key => $post)
    <div wire:key="{{ $key }}">
        <h1>Post {{ $key }}</h1>
        <label>Title: <input wire:model.defer="posts.{{ $key }}.title" required /></label>
        <label>Body: <textarea wire:model.defer="posts.{{ $key }}.body" required></textarea></label>
        <label>Image: <input type="file" wire:model.defer="posts.{{ $key }}.image" /></label>
    </div>
@endforeach

<button type="button" wire:click="savePosts">Update Posts</button>
  1. Update your savePosts method in the Livewire component to handle file uploads:
public function savePosts()
{
    $this->posts->each(function ($post) {
        $post->save();

        if (isset($post['image'])) {
            $post->addMedia($post['image']->getRealPath())->toMediaCollection('images');
        }
    });
}

In the updated code, we check if an image file is uploaded for each post. If an image is uploaded, we use the addMedia method from Laravel's Spatie Media Library package to save the image to the images collection associated with the post.

Make sure you have installed the Spatie Media Library package and set up the necessary configurations for file uploads to work.

Note: This solution assumes you have already set up the necessary file upload configurations in your Laravel application.

Please or to participate in this conversation.