My third portfolio project: Sinatra/React application

Katie Loesch
5 min readApr 3, 2022

Goals

  • The aim of this project was to create a Sinatra API backend that uses Active Record to access and persist data in a database.
  • Another objective was to build a separate React frontend that interacts with the database via the API, with the API routes handling various CRUD operations for the Active Record models.

The project: lists

I created an application that enables the user to make two different types of lists: a todo list and a shopping list.

The Home page allows the user to sign into their account and welcomes them if the email address and password entered match a record on the backend server.

Once a user is logged in they can access their todo list and shopping list. They can add new todos, delete items from the list and also filter the list according to different categories.

The shopping list component follows a similar structure, allowing users to add items, delete items and categorise them accordingly.

Database Structure

Items on these lists can be tagged with different categories in a one-to-many relationship:

  • Each todo item belongs to a todo category and each category can have many todo items. Each todo also belongs to a user and each user can have many todo items.
  • Similarly, each shopping item belongs to a shopping category and each category can have many shopping items. Again, each item also belongs to a user and each user can have many shopping items.
  • The tables for the todo and shopping items contain columns that store the foreign keys for the category and the user they belong to, illustrating the associations as shown in the ERDs below.

Migrations

I used ActiveRecord migrations and Rake tasks to create the appropriate tables in the database.

In accordance with the separation of concerns guidelines, the backend has separate classes for each those models, with the class names in the migration files matching their file names. The models inherit code from ActiveRecord::Base.

I used “has_many” and “belongs_to” to indicate the one-to-many associations and make common operations simpler and easier.

CRUD operations

The frontend component uses ActiveRecord to interact with the database and API routes built with Sinatra handle several different CRUD actions:

1. retrieving a list of todos/shopping item from the server

2. adding a new todo/shopping item to the list

3. removing a todo/shopping item from the list

The following snippets show the front end (left) and back end (end) code for the todo application:

  1. I used a GET request to retrieve all the todos in the database that matched a specific user.

2. To add new todos to the list I used a POST request to send data to the backend.

3. Finally, I used a simple DELETE request to delete specific todos from the server.

Challenges: Seeding the database

When seeding the database repeatedly with the same seeds.rb file, records are added multiple times resulting in duplicate data in the database.

Duplicate records are easily avoided with the “Model.destroy_all” method. This method deletes all existing records for the class it is called upon and gives you a clean slate to add records to an empty database.

However, “Model.destroy_all” does not reset the primary key sequence, which the database refers to when adding new records. Even after removing all existing data, the primary key will keep auto-incrementing when seeding the database, rather than starting again from 1.

One way to get around this issue is to use a the gem “activerecord-reset-pk-sequence”. After the “Model.destroy_all” method gets rid of all existing records in the database, “Model.reset_pk_sequence” will reset the sequence of a table’s primary key, so the key will start auto-incrementing from 1 again.

Conclusion

This was my first experience writing code for both the front and the back end. Although being a bit more familiar with React and JS, Ruby, ActiveRecord and Sinatra were new to me. In particular, I appreciated all the built-in functionality ActiveRecord offers for communicating with databases and how intuitive it is for someone new to programming.

This project has also taught me a lot about dealing with different types of error messages and how to use them to eventually get successful server responses.

I enjoyed interacting with the database components and look forward to learning about rails in the next phase of the program and diving deeper into backend architectures.

--

--