My coding journey: building a Contact Manager

Can I phone a friend for help…oh, wait, what’s their number again…?! | Image: Pexels

Weeks four and five at 8th Light were challenging but exciting as we took yet another step further into the world of Ruby and the Command Line. These two weeks were a real test of our understanding of what we’d already learned, and using this to solve a new, slightly different problem.

Our task began as below:

We were invited to present our program to the rest of the team at the end of two weeks.

Key moments from these two weeks:

Storing multiple contacts

Each contact would need at least four pieces of data stored: their first name, surname, email address and phone number. Working with Elle it became apparent that the best way to keep each entry was as a hash with four keys.

Using TDD, I again had to look at how to stub my input so that I could run tests in RSpec. Having used stub in Hangman I was familiar with this idea, but used an alternative version to suit this project: $stdin. I could define what the ‘standard input’ would be in my tests (essentially mocking the action of entering data) and check that the program was behaving as expected. I changed all my gets.chomp variables to stdin.gets.chomp allowing me to overwrite “gets” with the mock data given in my test.

Validating data entries

After refactoring some of my code, I was personally curious about how I could validate some of the entries to check that it was the right type of data. I added some steps to have the program check that the user had entered something which might look like an email address or a UK mobile number. To do this:

  • It checked through the email address characters to ensure there was an ‘@’ present
  • It checked the phone number to ensure that it was 11 digits long, and began with ‘07’

If the data entered didn’t match this case, it would prompt the user to enter a valid email or phone number.

This was a really interesting problem that could be developed much further to create a more sophisticated method for validation. Whilst I set my program to expect a UK mobile phone number, it’s quite possible that the user would have international contacts with a variety of number formats. Also, as noted in this issue, much more could be made of the email validation to ensure the input matched an expected structure, such as “user@domain.suffix”.

Having completed the core and stretch goals for the project in week one, our mentors came up with some additional goals in preparation for my presentation the following week.

Editing and deleting contacts

With a new week ahead I decided my first goal would be to delete a contact, following a similar logic structure to the method which allowed the user to search for a contact.

I researched how the program could be given a name by the user, search for that contact and delete them from the file. I found and implemented the .delete_if method. However, I found that it wasn’t actually deleting the contact, and whilst it was returning ‘true’ it seemed that the data hadn’t changed.

After a moment of thinking this through with Laurent I realised that I hadn’t told JSON to delete the found contact, and really began to understand the steps ‘read, parse and write’ when using a JSON file.

I had read and loaded (parsed) a copy of the current data in my JSON file, and run the delete instruction on that copied data. Yet my original file remained the same. Until I had saved the newly changed version of my data over the original, my JSON file didn’t know that it had been changed. Essentially I needed to let my file know that this version with the deleted contact removed was the version that I wanted to keep.

(loving these MASSIVE post-its!)

Viewing all contacts

I was able to get a full list of all the data to print to the console using .sort_by, returning a block of data with all the hashes in alphabetical order either by first or last name. However, the view of the data wasn’t very easy to read or a logical view for the user.

I researched a variety of options, including ‘pretty print’ and found a gem called Awesome Print. By typing ap I was able to get the contents of each hash to print on a new line, looking much more like a contact list.

On the right is the console view for ‘return ap @contacts.sort_by { |fn, ln, em, ph| fn[:fname]}’


Early Friday (23rd Nov) having downloaded postgreSQL, I looked at how to create a table from the Command Line in Terminal. With the support of one of our mentors Phil, I worked through the syntax of creating a table and viewing the contents of the table once values had been added. I really like the simple functionality of postgres and what the UI looks like in terminal.

I played around with this a bit more using a tutorial, learning how to create a table, add values, search for values and edit them, some of the things which I’d need my SQL phonebook to do.

The key takeaways I got were:

  • to make sure I had a ‘;’ at the end of each instruction
  • if i didn’t have a ; the terminal would go from postgres=# to postgres# meaning I’d done something wrong, and wouldn’t work. The way to get out of this is by hitting ‘CTRL + C’
  • the difference between integer (whole numbers only), numeric (decimal places and dates) and varchar (various characters, essentially anything else) when setting up my columns

I then worked through how to access postgres from my ruby file, so that I could eventually start to use a table to store my contact information.

Highlights from week four and five…

My highlights this week:

  • giving a presentation to fellow 8th Lighters to show my work on building Contact Manager. I was perplexed as to why some of the features I knew had been built weren’t displaying properly, but learned the valuable lesson of making sure you’re on the relevant branch when presenting (i.e. my ‘master’, rather than the unfinished ‘postgres’ branch I’d been working on that day!)
  • discovering the joys of PostgreSQL and tables
  • hearing the fantastic graduation presentation of one of the Resident Apprentices, who that day became a Crafter! ? ?

Things I’ve learned:

  • How to add circled numbers to my console using unicode
  • Working with multiple branches can be tricky. Always double check which branch you’re on when demoing your project!
  • The clear screen instruction for clearing the console view
  • How to read, parse and write data to a JSON file from Ruby

Things I’ve struggled with:

  • How to change a value in a hash based on which contact my user wanted to edit, and save the updated hash back into my JSON file. Much thanks to Devlin for pairing with me and helping to work through this.
  • How to use .delete_if to find and delete a hash from my JSON file.

Things I’m curious about:

  • how I can improve the validation — maybe there are gems which can check to ensure that the entry has a valid email address or phone number?
  • how Contact Manager might look or work if hosted online — how can I make it list the contacts ‘prettily’ on something other than the console?

What I want to focus on:

  • Using PostgreSQL with Ruby