I will breakdown the steps using 2 parts, one for the backend and one for the frontend.
Part I: The Backend
First of all, I will go over how to build the backend, which will be pretty fast as we already built a project using Ruby on Rails. I had to make sure to create a folder for the whole project, and then inside of this folder, create a folder for the backend that I called “restaurant-style-back-end” and push it to a new repository on Github : https://github.com/mattbertrand/restaurant-style-back-end
- Once created, the set up is fairly easy. You create a new rails app using the command: ‘rails new . — api’ (the dot is a way to create it inside this new folder and not adding another folder)
- Set up your models. I decided to go with a restaurant model that has a name and city, that belongs to a style that has a name. I decided to start very easy at first as I was not very confident, and later added an image and a link_url to my restaurant. To set up both of these models, I used scaffolding which set up 90 % of your controllers (CRUD actions), tables, routes and models.
- Model: Things I had to do was to add the associations in my models, create a custom association writer method for the restaurant to accept the style attributes.
- Controller: Add the style_attributes custom method in the strong params and in index and create actions, remove “created_at”, “updated_at” and “style_id” from render and include the “style” using:
except: [:created_at, :updated_at, :style_id], include: [:style]
- Don’t forget to add rack-cors gem to your gemfile just by uncommenting it (The CORS spec allows web applications to make cross domain AJAX calls without using workarounds such as JSONP) and also update the cors file in your initializer to include all (*)
That is about it for the backend, run “rails db:migrate” once you are satisfied with your tables and seed some data if needed.
For the frontend, I created a new folder inside of my project folder that I called “restaurant-style-front-end” and created a new repository on Github: https://github.com/mattbertrand/restaurant-style-front-end. This is my main repository that includes a link to the backend in the Readme.
- Inside of this new folder, I created folders and files like so:
3. The global.js will contain my global variables. A global variable has global scope: All scripts and functions on a web page can access it. For example, I have my constant “main” that will get the element by its “id” in the html:
const main = () => document.getElementById("main")
Note that I used an arrow function expression. An arrow function expression is a compact alternative to a traditional function expression, but is limited and can’t be used in all situations. In this case it is fine and makes the code looks cleaner.
4. Next the restaurant.js in my models folder. This file is home to the restaurant application code. It has a class Restaurant that is the blueprint of the restaurant Object. It has a constructor method so that we can create an instance of a restaurant with special attributes (name, city, image_url, website). By using
this.city to define properties in our constructor method , we can also refer to these properties within other methods of our class. This allows us to return dynamic information based on the unique properties we assigned back when an instance was created. These instances will be stored in an array using a static method. Static methods are class level methods - they are not callable on instances of a class, only the class itself.
5. New instances of a restaurant will then be saved when created and pushed into this array using the save and static create method:
This function will also create the “edit” and “delete” links using “addEventListener()” method that attaches an event handler to the specified element. This method takes 2 parameters, the first parameter being the type of the event, the second being the function we want to call when the event occurs.
Both functions are declared within this file and will have similarities like preventing the default on the event (e.preventDefault()) so that the page keeps from refreshing when the Fetch request is made. We then find the id of the restaurant that we want to edit or delete, and in the case of the “editRestaurant method”, we render the edit form for this restaurant and then we do a fetch patch request to update the element updating our Rails Api. In the case of a delete event, we prevent the default, find the restaurant by its id, send a fetch delete request to our Rails Api and then render the restaurants. All this happens in a blink of an eye.
This was definitely a fun but intense project to build. There is a lot more that I could have covered in this blog but I tried to do a resume of the steps that I took to build this project. There was a lot of refactoring to make my code DRYer and a bit of css to make the page look nicer.