warpig's avatar
Level 12

Multiple files upload

Hello guys Im trying to pass a request with multiple images like this:

     public function store(Request $request)
     {   
        $post = request()->validate([
            'title' => ['required', 'max:255'],
            'body' => ['required'],
            'image_url' => ['image'],
            'category_id' => ['required']
        ]);
        
        $images = $request->file('images');

        if(request('images')) {
            foreach($request->file('images') as $images) {
                $post['image_url'] = request($images)->store('faro_posts_img');
            }
        }

        $postObject = new Faro($post);
        $postObject->save();
 
        return redirect('/faro');
     }

But im getting a 302 response from the browser so that means its not storing any of my files. If i look on Sequel Pro nothing gets stored but the browser receives the request, under Network tab and responses I can see that what I input in the form fields it's there, and the PNG's as well.

I was able to look through some examples consisting of making galleries, others using Javascript but Laravel should be able to do this, right? What else does my code needs? Thanks!

https://rajivverma.me/blog/tech/multiple-file-upload-laravel/ <-- using a gallery https://www.cloudways.com/blog/laravel-multiple-files-images-upload/ https://www.youtube.com/watch?v=--9I5wqXgUM <-- using Javascript

0 likes
6 replies
tykus's avatar

You can check for the presence of files using hasFile; and each file in the array will be an instance of UploadedFile class; so store on each instance. Last, is the image_url field a string or JSON column type; because the existing implementation below will overwrite the stored file value for each file in the field leaving only the last:

if($request->hasFile('images')) {
    foreach($request->file('images') as $image) {
        $post['image_url'] = $image->store('faro_posts_img');
    }
}

You may find that you need an images table and hasMany relation to the Post class.

warpig's avatar
Level 12

@tykus the column type is a string column type. I created an images table and in this one there is a column called post_id how can I write to this column, wihch is another table?

Image model:

    public function post()
    {
        return $this->belongsTo(Faro::class);
    }

Faro model:

    public function image()
    {
        return $this->hasMany(Image::class);
    }

Is this okay?

tykus's avatar
tykus
Best Answer
Level 104

First, make the relationship named images to describe it properly.

Then, you need to first store the Post (so you have the Post id for the post_id foreign key), then use the relationship to set the path in the images table:`

$postObject = Faro::create($post);

if($request->hasFile('images')) {
    foreach($request->file('images') as $image) {
        $postObject->images()->create(['image_url' => $image->store('faro_posts_img')]);
    }
}

You will need to organise the data array to pass to the create method; only Post data, not images.

warpig's avatar
Level 12

Ok, please take a look at this:

    public function up()
    {
        Schema::create('images', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->unsignedBigInteger('post_id');
            $table->timestamps();

            $table->foreign('post_id')
                ->references('id')
                ->on('faro_posts')
                ->onDelete('cascade');
        });
    }

I have removed the images validation, is that fine? it's not a required field so.. and the relationship has been renamed accordingly

I still get an error and I can't remember how to fix it, is when you are trying to use a different name for a column but since Laravel will auto-name columns regarding the table name, for example since my table is named "faro_posts" it's trying to find "faro_id" but im using "post_id":

    public function post()
    {
        return $this->belongsTo(Faro::class, 'post_id');
    }

Just removing that error and then I will be able to test store(), this is how it's looking so far.

     public function store(Request $request)
     {   
        $post = request()->validate([
            'title' => ['required', 'max:255'],
            'body' => ['required'],
            'category_id' => ['required']
        ]);

        $postObject = Faro::create($post);

        if($request->hasFile('images')) {
            foreach($request->file('images') as $image) {
                $postObject->images()->create(['image_url' => $image->store('faro_posts_img')]);
            }
        }

        $postObject->save();
 
        return redirect('/faro');
     }
tykus's avatar

Remove this line, it is persisted using create

$postObject->save();

Change this to match the name column on the images table.

$postObject->images()->create(['name' => $image->store('faro_posts_img')]);

I still get an error

Can't help without knowing the error message.

warpig's avatar
Level 12

Yea the error I figured that out, actually after fixing that the name column wasn't being written on but this line fixed it:

$postObject->images()->create(['name' => $image->store('faro_posts_img')]);

and yea that is working.

Please or to participate in this conversation.