brentxscholl's avatar

Handling image uploads for a model that has not been created yet

In my project I want my users to be able to post Events.

Events have a title, description, price, date, start time, end time, images, etc.

When a user is creating an event, I want them to be able to upload images as well.

This image upload form is on the same page as the event creation form.

I'm using an ajax image uploader so that the user can see image thumbnails in real time and drag and drop the image order. (user selects an image from device, it automatically uploads using ajax, and the image thumbnail sections updates on successful ajax call showing the newly added image(s). this ajax form is outside the events form, but on the same page)

The problem is that when I upload the images using ajax to show on the page, the Event has not yet been created by the user so an event_id can not be attached to the Image model.

It works if I'm editing an Event because there is an event_id for the image model.

How do I handle adding images using an ajax image uploader to an event that has not yet been created? Is there a way to store them in the session and if the user does not create the event (navigates away from/ refreshes the page) the images are removed/not saved.

Note: This would be a heck of a lot easier if i just used a multifile input in my form, but for the sake of User Experience, it is required that the user instantly see thumbnails of the images they plan on attaching to the event and be able to drag drop, and delete them on the fly, while in the process of creating events.

0 likes
3 replies
bobbybouwmann's avatar
Level 88

Well you have two options here. Either upload the images and attach them later to the event whenever it's created or create the event before you go to the create form.

So for the first option you can store the path to the event in the session for example and then later reference that session to attach the images. However when images are still in session and the user click away the browser you probably have some images on your server that have never been attached to the event. You can for example store the images in a different location when creating and still save the reference in the session. You can then have a cronjob running everyday to clear out the images in that directory. Once the user saves the form you move the images to the correct directory and they will never be deleted.

For the other solution you kinda have the same problem. You can create the event beforehand and show that to the user, this way you already have an id. However this also means that if the user never finishes creating the event you have an empty event hanging around. This makes it easier for the image upload part, but you're still stuck with dangling events. You can for example set a flag on if it's been created by the user or by the system so you know which one you can delete, including the connected images.

Personally I would go for option one since you need to find a solution for the images and not for the event itself

2 likes
brentxscholl's avatar

@BOBBYBOUWMANN - Thanks a lot for the reply! Option one sounds like the best option using a temp folder and cronjob. Great stuff! Thanks again for the help!

JohnBraun's avatar

As an addition to @bobbybouwmann 's answer: I've worked on a project where I did a similar thing, but using option 2.

Option 2

In the Order model, I had defined the function: currentOrder(). For the create route (which shows the form) I grabbed the users current order (auth()->user()->currentOrder()) which either created a new one and associated the order with the user or used the existing one.

Now, if you replace 'Order' with 'Event' I think you have a (partial) integration of option 2.

// User.php

public function currentOrder()
{
    if ($this->orders()->open()->count() < 1) {
        return Order::create(['user_id' => $this->id]);
    }

    return $this->orders()->open()->first();
}
// OrdersController.php

public function create()
{
    $order = auth()->user()->currentOrder();

    return view('orders.create', compact('order'));
}

Please or to participate in this conversation.