DEV Community

Cover image for Arcadia: A Full-Stack App
Fredie Aponte
Fredie Aponte

Posted on

Arcadia: A Full-Stack App

Riding the Rails

Learning the core fundamentals of both front-end and back-end languages has been a rollercoaster of trial and error. Ultimately though, I have made it to this current point: creating a full-stack web app that I am proud to call "Arcadia"! The program utilizes Ruby on Rails back-end server side and React front-end UI to provide an arcade rating experience.

Creating the Back-End

To start off process, Rails had to be configured to not only initialize with the prefix client, but also accept cookies and store in sessions with middleware. Once configured I can move on to creating the database. The first to get created are my models. There are three of them: User, Arcade, and Review. Each model will have their own attributes pertaining to themselves, such as 'name', or 'username', with the join table of reviews containing a 'body' attribute along with 'user_id and arcade_id'.

Here, the Arcade is the resource that will be joined to Users via the Reviews table. Arcade has many reviews, and has many users through reviews. Users has many reviews, and has many arcades through reviews. Once the attributes are declared, I run the migrations to create the database table.

To return specific JSON I'll need to create some routes for each of the models. In this application, my intention is to have full CRUD capability in the Reviews model, with only Create & Read functionality to the rest which the exception of Session(more on that later). I can return specific JSON in the response to the request by the client with what are called Serializers. Serializers allow me to literally pick and choose which attributes I want to return, or add to, to return as JSON. This is especially useful for omitting automatic attributes like timestamps when models are created, and so on.

I can now move on to creating controllers. Each controller will belong to a model and be responsible for providing methods associated with the model's routes. These methods are called 'actions' and are what drives the logics behind client requests and server responses. Here, you can provide the validations (in the models) and handle error logic as well. What this means is, whenever a user is looking to create data with bad input, the controllers responsible can reject the submission, provide an error in response, and it also will not persist that bad data to the backend.

Diving into controllers, we can create a "sessions controller" which is responsible for logging in a 'User' to the app through cookies and sessions. When a user submits through a login form their username and password, the sessions controller will run an authenticate check to see if the password hash provided matches that of the users login info. This is thanks to the ruby gem 'BCrypt'. This gem provides us a way to safely store user login information without it being compromised.

The way my application controller is set up, I made it so that all the error handling logic can be contained in the applicationController and all those actions can be inherited by the rest of the controllers. This allows for cleaner non repetitive code. Once the authorization and authentication protocols were established, I can move towards the front-end UI side of things.

The way I tested my api without a proper front-end in place was by using Postman. I've had to "skip before actions" of authorizations just to test that that JSON I requested responded as such as the way I intended them to. Once I ran my migrations and seeds I felt everything was good to go.

Login & Authentication

The authentication/ authorization logic is mainly housed in the back-end. However, thats not to say you could not hold conditional rendering into the components you render on the front-end! For instance. There are URL routes that will lead to lists of Arcades and or Reviews. Unless you are actually logged in, you cannot ( or should not ) be able to even see the data that belongs there. A better case is saying, when in the home page of the app, if you are not logged in, will see a message stating to signup or login to use features. When you log in, that same home page will display different data; Like your Username and maybe the reviews you have written.

Ive Learned how important it is to protect your URL routes as well as back-end routes from unauthorized querying. It is critical to understand how forgetting to cover your tracks can lead to unwanted exploits from malicious users.

Front-End UI

The UI was relatively simple. I first started with using a react hook called 'useContext'. The way I understand it, basically, is a way to provide "props" to any child component without the need to prop drill. That is FANTASTIC! With that said, I created the a context file for User that will hold in state whether or not a user is 'logged in' or not. I can then pass that state to any child component that needs it.

I started with the Navbar. Once I made a route to home ('/') the Navbar will decide whether tho show the Login, and Signup buttons. Once a User does either, the User object will be in state and a boolean of "loggedIn' will set to true. This simple state passed down to children easily allows for ternary or conditional rendering! When a user is 'logged in' the context keeps the current logged in user object in state. As soon as they log in, the Navbar will show a 'log out' button that will reset the context to empty objects and false boolean values.

All that was left to be done was to tidy up the rest of my components. I made routes to the arcades that you can only access when logged in. If you were to enter into the URL bar:'.../arcades' to try and access that route manually, you will be met with not only an unauthorized error message in console log, but also the /arcade route rendered will display in UI that you must be logged in. That is the magic of the conditional rendering on the front-end!

The Full-Stack

It was tricky to completely code the UI after completing the back-end as I should have used a more vertical approach to its development. It would be best to work on the login/signup features first. This way saves a ton of error messages and angry exceptions...All in all, its relieving to see Arcadia in its finality and realize the potential for future apps to come.

Top comments (0)