AlexanderKim's avatar

How to store multiple images paths in database?

I have input with multiple attribute, that allows multiple image uploads. However if it'll be a single image input, then i have no problems to store it's path in a database, but how to store multiple paths in a single column, something like how to insert an array in to a database?

I save images this way:

        if ($request->file('images')) {
            $images = $request->file('images');

            $filenames = Str::lower(
                pathinfo($image->getClientOriginalName(), PATHINFO_FILENAME) . '-' . uniqid() . '.' . $image->getClientOriginalExtension()
                );
            $destination = 'uploads/';
            $images->move($destination, $filenames);

            $product->image = $filenames;
        }
0 likes
18 replies
BishoyWagih's avatar

you have two options,

1 - you can create pivot table to store product images which is better solution for me

2 - to save an array into database just in your model define a casts property for this database field like

protected $casts = ['imagesColumnName' => 'array'];

then in your controller do what you were doing

$product->image = $filenames;
1 like
AlexanderKim's avatar

That DB column could be a string, right? Pivot is much better, but it's extra table in DB, these images would be used only inside a product page.

BishoyWagih's avatar

database column will be text for more extra size,

i prefer working with pivots rather than serialized array, you can easily update, delete records from pivot table..

Sergiu17's avatar

You create a separate table in your database with fields id, product_id, image

$product = new Product();
$product->save(); // you need to save product before adding images

$images = $request->file('images');

foreach($images as $image)
{
    $name = Str::lower(
                pathinfo($image->getClientOriginalName(), PATHINFO_FILENAME) . '-' . uniqid() . '.' . $image->getClientOriginalExtension()
                );

    $images->move('uploads/', $name);

    // this is the reason of saved product
    $product->images()->create([
        'image' => $name,
    ]);
}
1 like
AlexanderKim's avatar

@Sergiu17 if i save without image, then i can't make the image required, right? I want to force people to upload images.

Sergiu17's avatar
Sergiu17
Best Answer
Level 60

@AlexanderKim from your create_products_table.php migration, you completely delete $table->string('image');, now create new migration create_product_images_table with id, product_id and image, and you leave images field required

AlexanderKim's avatar

Wait, do i have to make any changes to my Product model?

Do i need to create Image model now? And make One-To-Many relation?

Sergiu17's avatar

Do i need to create Image model now?

Yes

class Product extends Model
{
    public function images()
    {
        return $this->hasMany(ProductImage::class);
    }
}

class ProductImage extends Model
{
    public function product()
    {
        return $this->belongsTo(Product::class);
    }
}
AlexanderKim's avatar

I just realized, why do i need a pivot table? I can create just OneToMany relation, right? I mean i don't need that pivot table, just a ProductImage table. Also i don't need that reverse relation.

Sergiu17's avatar

@AlexanderKim No, you don't need pivot table, you need just product_image table, and yes, you don't need reverse relation

1 like
AlexanderKim's avatar

Also, how can i delete all images (DB entries), when i do:

$product->delete();
Sergiu17's avatar
$product = Product::find(1);
$product->images()->delete();

Ohh, wait, this is at the Database level, when you create your foreign key relationship in your schema, add onDelete('cascade')

$table->unsignedInteger('product_id');
$table->foreign('product_id')->references('id')->on('products')->onDelete('cascade');

And now, when you do

$product->delete(); // all the images will be deleted automatically
AlexanderKim's avatar

I've read about using Foreign Key Constraints at schema level for deleting associated images, why would i need this, could you explain, please?

AlexanderKim's avatar

$table->unsignedInteger('product_id'); $table->foreign('product_id')->references('id')->on('products')->onDelete('cascade');

Is that preferable method over $product->images()->delete(); ? What drawbacks if i just use $product->images()->delete();

Damn, so many ways to do a things, that freedom is sometimes bad :D

Sergiu17's avatar

@AlexanderKim use onDelete('cascade');, it's at the database level and less code to write in php.

$product->images()->delete(); this is when you need to delete all images but keep the product, or idk, nothing comes to my mind right now

Please or to participate in this conversation.