Ifrit's avatar
Level 2

Saving multiple images

I'm trying to save multiple images in an array to the database, but I'm struggling with that. I've managed to be able to upload the multiple images to the folder just not the database.

My controller

public function store(Request $request)
    {

        $content = new Content();

        $request->validate($this->getRules());

        $content->fill($this->getSafeInput($request));

        if($request->hasFile('image'))
        {
            foreach($request->file('image') as $image)
            {
                $destinationPath = 'content_images/';
                $filename = $image->getClientOriginalName();
                $image->move($destinationPath, $filename);
                $content->image = $filename;
                
            }
            
        }

        $content->save();
        
        return redirect()->route('content.index');
    }

My form

<div class="content-form">
    {{ Form::open(array('route' => 'content.store', 'method' => 'post','files'=>'true' )) }}
        {{ csrf_field() }}
        
        <div class="form-group">
            <label for="title">Title</label>
            <input type="text" id="title" class="form-control" name="title">
        </div>

        <div class="form-group">
            <input type="file" name="image[]" multiple="multiple">
        </div>

        <input type="submit" class="btn btn-primary" value="Submit"></input>
    {{ Form::close() }}
</div>
0 likes
2 replies
bobbybouwmann's avatar

If we look at your code we see that your $content->image call is called for every image. This means that it will override that. What you want here is a relationship between content and images. You can of course save it as an array in your database, but then you will have a hard time removing one image for example.

Here is an example with the relationship set up

$content->fill($this->getSafeInput($request));
$content->save();

if($request->hasFile('image')) {
    foreach($request->file('image') as $image) {
        $destinationPath = 'content_images/';
        $filename = $image->getClientOriginalName();
        $image->move($destinationPath, $filename);

        $image = new ContentImage([
            'path' => $filename,
        ]);

        $content->images()->save($image);
    }
}

Now that we have this working we also need to create the relationship. For the you need an extra table in your database and also an extra model.

// create_content_image_table

Schema::create('content_image', function (Blueprint $table) {
    $table->increments('id');
    $table->integer('content_id')->unsigned();
    $table->string('path');
    $table->timestamps();
});

// Content.php

public function images()
{
    return $this->hasMany(ContentImage::class);
}

// ContentImage.php
public function content()
{
    return $this->belongsTo(Content::class);
}

For more information on relationships read this: https://laravel.com/docs/5.5/eloquent-relationships#one-to-many

Let me know if you have more questions ;)

emads3's avatar

I have simple modification on @bobbybouwmann snipped. You should extract extract the calls to database outside the foreach block and use createMany instead

if($request->hasFile('image')) {
    foreach($request->file('image') as $image) {
        $destinationPath = 'content_images/';
        $filename = $image->getClientOriginalName();
        $image->move($destinationPath, $filename);

	$allImagesPathes[ ]['path'] = $filename;

    }
    $content->images()->createMany($allImagesPathes); // this will save you tens of DB quires
}

Please or to participate in this conversation.