How Developer Solve Problems (Project | Travel Log)



The first idea of Travel Log project was making a personal album app that allows the user to easily organize travel photos by location. In this blog post, I will talk about some of the issues I had while building the frontend to make the backend work and how I solved it.

The ultimate goal of this project was to make sure that the uploaded photos are linked to where they were taken. To achieve that goal, I have established two essentials: using an external map API to visualize travel history and creating backend storage to save uploaded photos. 




## Faced the problem

When building the backend, I made 3 main tables: User, Film, and Photo




The main problem I struggled with was how to get the Film and Photo tables to work properly. For this project, I used Active Storage with Rails. Photo table handles those photos in the storage and it is dependent on the Film table which stores travel information. The mechanism of these tables is whenever the user uploads new travel information, each information is stored in corresponding table and the photo the user uploaded is automatically saved in Active Storage table (which is different with Photo table).

With Active Storage, these unnecessary steps are used, which created problems while building the frontend. The first design of uploading page was handling post request of both tables.




The problem with this design was that post requests from the Photo and Film tables were executed concurrently. The post request of Film table must be executed before the associated post request of Photo table because it needs 'film id'. Film id is generated upon its post request.




If both data are created at the same time, the data stored in the Photo table loses the film id, which is the only link with travel information. After much thought I came up with two options.




## Option 1: Use POST and DELETE requests whenever entering information

The first idea that came to my mind was a very clunky way to run a POST request when each piece of information was entered and a DELETE request if I went to another page without pressing the submit button. This method is very straightforward, but at the same time error-prone. The main reason was a lot of data movement, too many requests were executed at once and were often overlapped. It also slowed down the server as data moved back and forth between the frontend and the backend every time the user entered the information.

(Notes written at the time)


Other than that, I decided to move on to the next option because of several factors, including the need to create unnecessary buttons that interfered with the user experience.




## Option 2: Divide into two pages that can handle each Film and Photo table

This idea came to me after a whole day of thinking after constant errors in my first design. I eventually decided to divide it into two pages: one for managing travel information and the other for storing photos.

(Next button fires POST request of Film table)

(page dealing with photos)


This way I was able to solve all the issues mentioned above! Post requests of the Film table are executed before requests of the Photo table, so each photo can have a film id. This design was also a way to get rid of unnecessary requests. The act of pressing the next button by the user was the same as confirming the storage of the travel information submitted by the user. The post request is not executed unless the user clicks the next button.

I was able to find one laxity in this part. What if the user clicks the next button and goes to another page without saving the picture? If so, the travel information is stored in the Film table, but the associated photos are nowhere to be found and cannot be saved again. So I ended up adding a new category called 'pre-released'.




First, I added a new attribute called 'isReleased' which is a boolean attribute so I can sift through whether the data has an associated photo or not.




Whenever the user clicks the next button, a POST request for the film data is executed with a false value stored in the 'isReleased' property. If 'isReleased' is false, a card is automatically created in a space called 'pre-release films'. I created an edit button there, and when the user clicks it, it takes them to the page where they can manage photos and travel information.






The moment the user clicks the 'Submit Film' button, a POST request is executed in the Photo table, and 'isReleased' is fetched with a value of true. That means that the card that was on the Pre-release Films page is gone and the photo data linked to the travel information is finally saved.




Then I added some touches to make the user's photo show through in a shape reminiscent of an airplane window.




## Conclusion

The process of development is like solving an ongoing puzzle. This project in particular taught me a lot of ways to solve problems. It had a deadline, which also affected many areas while solving the problem. Many parts were removed in order not to waste time, and there were times when I had to give up boldly. I am satisfied with the result as it is a work that taught me a lot in many ways.

My next step will probably be to try using a storage other than Active Storage because, from my point of view, Active Storage had a lot of unexpected errors and there were still many parts that I felt needed more updates. I'll do some more research and come back to the blog post.

Happy coding!