Module one final project @ Flatiron School — Trip logging app

Manon Jacquin
4 min readMar 31, 2019
With ❤ from my terminal

For this project, I chose to build a trip logging app. Travelers can create an account, save and delete trips, keep track of them, associate activities with their trips, and write a post about an activity. Travelers can also browse the world with an interactive world map in the terminal, as well as get more info on a country they are curious about. Let’s dive in!

Context

For the Module One final project, we had to build a Command Line CRUD (Create, Read, Update, Delete) App that uses a database to persist information. As it suggests, the user interacts only with the Command Line.

This project emphasizes on the following skills:

  • Ruby
  • Object Orientation
  • Relationships (via ActiveRecord)
  • Problem Solving (via creating a Command Line Interface (CLI))

Project set up

Goals:

  1. Create models and tables with a join table.
  2. Access a Sqlite3 database using ActiveRecord.
  3. Define user stories and allow users to interact with the database via the CLI.
  4. Be aware of Object Oriented design patterns.

My application contains three models: Traveler , Trip and Activity and three tables: travelers,trips and activities.

The relationships between them can be written as follow:

  • A traveler has many activities
  • A traveler has many trips through activities
  • A trip has many activities
  • A trip has many travelers through activities
  • An activity belongs to a traveler
  • An activity belongs to a trip

I created the associations between all the models as follow:

# lib/models/activity.rb
class Activity < ActiveRecord::Base
belongs_to :traveller
belongs_to :trip
# lib/models/traveler.rb
class Traveller < ActiveRecord::Base
has_many :activities
has_many :trips, through: :activities
# lib/models/trip.rb
class Trip < ActiveRecord::Base
has_many :activities
has_many :travelers, through: :activities

Activities table is, therefore, the link between Trips and Travelers

After migrating my tables to the database, we get this schema:

 ActiveRecord::Schema.define(version: 2019_03_25_164343) do

create_table "activities", force: :cascade do |t|
t.string "activity_name"
t.text "comment"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "traveller_id"
t.integer "trip_id"
end
create_table "travellers", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "trips", force: :cascade do |t|
t.string "city"
t.string "country"
t.string "continent"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
end

Now I have my models and tables, and I also have access to a sqlite3 database thanks to ActiveRecord. It’s nice to have the structure but how am I going to allow my users to interact with the CLI?

The CLI

The CLI is where I define the methods of the CRUD. The CLI is a simple ruby file where I will define the start method which will be called in my Rakefile:

require_relative 'config/environment'
require 'sinatra/activerecord/rake'
desc 'Run the app'
task :run do
cli = CLI.new
cli.start
end

Run the app

Quick set up

  • Fork and clone my repository
  • Run bundle install in your terminal to install the dependencies needed.
  • In order to view the world map in your terminal make sure to install mapscii as such: sudo npm install -g mapscii , if you don’t the app will break.
  • Run rake db:seed to get the database.

Start the app

To start the application: rake run in your terminal.

Nice!!

Go for TTY !!

For this project, I used TTY-Prompt, a Ruby gem that made my life so much easier to prompt the user in the command line and retrieve its input. Let me give you a quick overview:

I got this beautiful menu using one of tty-prompt methods:

choices = {        
'Trips': :trips,
'Activities': :activities,
'Browse the world': :browse,
'Exit Travel Ta Life': :quit
}
answer = @prompt.select("What are you up to?", choices)

You can also collect more than one answer using collect, it looks like this:

def add_trip    
puts "Create a new trip below: "
new_trip = @prompt.collect do
key(:city).ask('City?')
key(:country).ask('Country?')
end

Pretty cool right?

Get country facts with the restcountries API

One of the application functionality is that a traveler can enter a country is interested in and get back some pieces of information in the terminal about that country.

For that, I used the restcoutries API (free and no key is necessary):

Browse the world…

If the user selects the option get real in the Browse the world menu, he will get the world in his terminal, so cool:

We can zoom in, zoom out, and use arrows keys to explore our world! For that I used mapscii. Check it out, it’s pretty cool.

Last words

It was a great week where I learned so much building this project on my own. I used git and GitHub to commit and push, created new branches every time I was working on a new feature, really I felt like a real developer building this little CLI app!! So much fun! I can’t wait to move forward and build real web app… 🙌

--

--

Manon Jacquin

Fullstack Developer ~ Writer - Perpetual Adventurer