Life Story™: A Sinatra App Recording Your Important Memories | Ruby

I tend to be very sentimental about things that happened in the past — they remind me of how I came to be myself today. I collect receipts, postcards, ticket stubs, pieces of written notes, small totems that instantly bring me back to that moment, at someplace, with somebody or just myself, thinking I do not ever want to forget this.

That’s how Life Story became an idea. I want to build an app that will not just remind you how many days have passed since, but also help you keep a note of the details of what happened, how you feel, who you share it with, and what it means to you. At the end of the day, the goal is that however tired and bored of life you may be, when you open Life Story, those moments flow back to you and you realize what really is important.

Step 1: Model Relationships

The Model–View–Controller (MVC) pattern is a paradigm framework that developers follow to separate the tasks of one integral program into three distinctively functioning units. Models are where objects are created, and how they relate to each other determines the underlying data structure that the application sits upon. Views control how the application presents its data. This, as I later discover, requires a lot of design and maneuvering to make the program look as you intend it to. And Controllers relay the requests and information back and forth between your application and the browser.

To map out the logic of the program, my first step is to decide which models to build and the relationships between them. For my app, there are:

  • Users —A user has a username, email, and password. Each user can have many stories and many categories through stories.
  • Stories — A story has a summary, a date, and a description. Each story can have many users but belong to only one category.
  • Categories — A category has a name. Each category can have many stories and many users through stories.
  • User-stories — Because the many-to-many relationship exists between Users and Stories, a join table is needed to store the various combinations.
Database Structure

Setup 2: Configure Environment

Once the basics are clear, the next step is to configure the environment and database for the program. When searching for a way to create scaffold easily, I found this gem Corneal made by another Flatiron School student that works like a charm. It generates the entire directory with a single command. Kudos to thebrianemory for making the life of a beginner programmer easier.

So I required gems that are most essential to my app in the Gemfile. Among which,

'sinatra' - the Ruby web application framework that this app is built with;'activerecord' - a Ruby gem for working with Relational SQL Databases;'shotgun' - another Ruby gem that hosts the application with automatic code reloading;'pry' - the miracle tool that intercepts the program in the middle and opens up a console for debugging;
Gemfile

Established connection to the database:

Environment.rb

Made a Rakefile to run routine tasks such as debugging much more quickly:

Rakefile

And set up config.ru, the entrance to my app and where the environment is loaded and all controllers are mounted:

Config.ru

Step 3: Create Migrations

It’s time to create some tables! Using Rake, migrations can be done with just:

$ rake db:create_migration NAME=create_users

This automatically generates a time-stamped file for migration. Defining the table using ActiveRecord conventions renders:

After all the tables are created, run migrations to move them to the database:

$ rake db:migrate

Following the model relationships as described previously, the database schema for my application looks like the following:

Schema.rb

Step 4: Add Controllers and Views

Controllers route user requests and Views render the subsequent content. Collectively, they determine the user experience on the app.

For the simplest functionalities, I added two controllers that inherit from the main Application Controller:

  • A User Controller — that enables users to sign up, log in, and sign out.
  • A Story Controller — that allows users to create, read, update and delete content. I will also allow one to view stories by date, category, and users.

It helps to define two helper methods in the Application Controller. In this way, those methods will become readily available subsequently in the views:

 helpers do 
def logged_in?
!!session[:user_id]
end

def current_user
User.find(session[:user_id])
end
end

From this point, the work is iteratively creating, testing and fixing. Among lessons learned,

  • Always be careful to guard all your Get requests so that they cannot be hijacked;
  • Seed the database with some initial data to help with testing. Check database often because some bad data you entered during development can just be the reason blocking your application;
  • Be patient to tweak the format, the fitting, the floating left or right. So much can be learned in HTML and CSS styling.
  • Add a couple of alert messages to let users and yourself know what part went wrong. Use pry diligently!

Start writing Life Story™

Life Story is perhaps going to be a continual passion project for me, and it is far from done. I will continue adding new things and hopefully follow up with later posts about how it has improved.

This gem is now published at RubyGems.org: https://rubygems.org/gems/life-story/versions/0.1.0

View the Github Repository here: https://github.com/sophieqgu/life-story

You can try it out by entering the following command in your terminal:

$ gem install life-story

Locate the directory where the gem is installed, and run:

$ shotgun

That’s it! Let me know what you think.

Photo by Colton Duke on Unsplash

Blockchain. Coding. Social Impact.