Ruby on Rails Bootstrap AJAX

In order to alleviate their workload during the busiest times of the year (spring and christmas), Mamiche called me back to develop a new take-out service. This time, no e-commerce tools were used to pre-chew the work, the app had to be built from the ground up. 100% custom-made.

This project is unrelated to my first work for Mamiche which focused solely on their Delivery service. This one started out as a paper ordering form which clients could fill out by hand and then comeback to take out their order once ready. The form needed to be "digitized" or so I was told. When it was first shown to me, I thought it would be very easy to implement on Mamiche's website, since it consisted of a list of inputs paired with a group of people preparing the orders, one by one, behind the counter.

1-fiche An old version of Mamiche's ordering form - filled by hand.

It turned out a lot of improvements on their old system were needed, and it was not going to be just a simple form anymore : order limits, inventory tracking, strict opening days, ordering hours, store selection, take-out slots, production totals, etc. Without the confidence to meet all these requirements with a pre-configured e-commerce solution, I decided to roll up my sleeves and do it myself.

2-schema The schema as a mindnode.

I laid down a map of the schema and built a total of 8 models (Cart, LineItem, Order, Store, Slot, Stock, Product, Category). At first, I thought of using a multi-step form to collect the starting input (store, date, slot) but it turned out to be easier to do it one single form.


3-form-start Listening to each field here in order to update the others.

Here's how it works : a new cart is created once the user has picked an available slot (which depends on a date and store) with zero items in it. Here the date UI is handled by Flatpickr.

4-cart The cart. A damn long form. User is provided with availabilities that are updated when the cart is submitted.

Once created, the cart can be edited - meaning line items can be added (a line item consists basically of a product and a quantity). Here I had to implement a few methods to create & delete line items, and add & substract their quantities. Since each of these methods would generate a new request and refresh the page, I used the built-in Ajax functionality of Rails for a smooth cart operation.

5-checkout The final checkout form.

Once the user is happy to checkout, personal details are requested (name, surname, e-mail, phone, etc.). It is the last part of the form since no payment is captured in this app (clients pay at the counter when they collect their order in person). Behind the scenes, the phonelib gem makes sure the phone is valid while simple_form checks out the email's validity. If validation requirements are met, the client gets an email and an approval screen. Otherwise, flash messages are triggered. And voilà! A takeaway order has been passed.


Let's take a look at the backoffice now. It consists of 4 parts which are accessible at all times in the navbar once the admin is logged in : the orders page, the products page, the production page and the slots & stocks manager.

6-orders The orders page.

The orders page lists outs all the orders. Here the admins can filter out orders by store, by date or perform a keyword search applied on the clients or order details. Orders are limited to 30 per page thanks to the pagy gem. Finally, the admins can also print out all the receipts corresponding to the query in one click !

7-products Some sections of the products page (not in order of appearance).

The products page allows to edit products and their corresponding categories. The particularity of Mamiche's takeaway product is that they are either sold by weight or by unit, and can be precut or not. These settings can be defined by the admin and are at the customer's disposal when filling out the order form.

8-production The production page - looks like there's not much to prepare for Christmas Eve here, is Santa on a diet or what ?

The production page is basically a big table which sums up what the bakers must prepare for any given day. It also uses the flatpickr gem and groups the different orders by slot, by category of product, for each store.

9-planning The slot manager - Once a slot has reached its maximum order capacity, it automatically closes and cannot be selected by other clients.

Because Mamiche's team cannot handle takeaway orders everyday (their stores are already super crowded), the slots manager is important. It allows the admins to set the products stocks for each slot and the maximum number of orders that can be passed in a slot. To build this, I used the simple_calendar gem which blends in super well in rails (it uses erb templating) and thus can be easily styled with bootstrap.

Finally admins have also the possibility to close the takeaway which presents the user with a redirection screen, while maintaining the backoffice open for operations.

Closing up

Overall this project was very satisfying for me. It showed me once again how fast and powerful Rails is for SaaS-like projects and how much more control you can have by building from the ground up. My only regret is that I slacked off a bit on styling due to lack of time : since it is an adjacent app to Mamiche's main e-store, I relied shamelessly on Bootstrap. But hey, it gets the job done.