To mark the conclusion of Module One of Flatiron School’s Software Engineering Immersive program we were assigned partners and challenged to build a command line database application. The provided instructions allowed for a variety of directions for this project to be taken in however as comic book fans my partner and I were immediately drawn to the Marvel API as our jumping off point.
Our task was as follows:
- access a SQLITE3 database using ActiveRecord.
- create a minimum of three models including one join model.
- To seed the database using information collected from a CSV, scraping a website, or an API.
- create a CLI to display the return values of methods displaying information from the database
In our initial brainstorming session we landed on the idea of an application in which a user would be able to save Marvel characters and storylines for reference and receive suggestions for related content (e.g — all characters in a saved storyline).
Initially we wanted our project to have a total of six models (User, StorylineCards(join), Storylines, CharacterCards(join), Characters and Appearances) however drawing the relationships out made us realize that we needed to narrow the scope of our project. As such, we decided to focus on three models for our first iteration: User, Character and CharacterCard (our join class). A User would be able to have many characters “saved” through CharacterCards and be able to query the database of all Characters available.
My project partner found a Ruby wrapper for the Marvel API that would allow us to call on the Marvel API using built in methods which would return an array of Hashie::Mash objects for us to seed our database with.
Utilizing the gem marvel_api we were able to seed our Character database however it did come with a few difficulties:
- The Marvel API itself had its limitations for characters called at one time (100 max) and in one day (3000 calls)
- An API key was required and thus needed to be hidden before pushing up to Github
Users were created by using the Faker gem to randomly assign names (in our demos we used Zelda characters). We wanted our users to also have characters “saved” via CharacterCards (join class) so we used the sample to randomly associate a user with a character via a new CharacterCard.
Now that we had our database seeded with 200 Marvel characters, 10 random users and CharacterCards to associate the two we began to build out our CLI. Early on in this process we realized that we would be creating multiple menu options in our CLI file that would call on helper methods within our User and Character class files.
Now that we had our models set, database seeded and CLI working it was time to make our program easy to read and navigate.
Using an ASCII text generator we created a more dynamic opening screen for the program. However, we chose a font that included escaping characters (“\”) which required further manipulation to properly show when ran in terminal.
We used the gem terminal-tableto represent the information from our database in a simple ASCII table. We also added in helper methods in the CLI menu that would return a user to the menu options they were previously in after they received the requested information.
After completing the first iteration of our project we set our sights on building out the stretch goals for additional models and associations. We ended up creating “Event” and “EventCard” models which would allow us to associate the names of Marvel events with Characters. However we immediately ran into an issue — how would we build those associations when seeding our database given the limitations of the Marvel API ? The solution we devised would be to find or create the Event within the Character creation then associate the character to the event by creating an EventCard. Once we had our expanded database seeded to our satisfaction we quickly added additional helper methods and menu items to navigate the expanded project.
I took away two important lessons from this paired programming project — ask for help early and set aside time to test your program as much as possible.
On day 4 of our project my partner and I had finished the first iteration of our project and were brainstorming ways we could expand to include our stretch goals. However, this brainstorming session fell victim to us talking ourselves in circles for hours rather than bringing in outside counsel. After reaching out for help the next day we realized that we had wasted essentially three hours by not simply asking for help!
A hour before we were set to present our project to the class I was recording a demo for our finished second iteration of our project when I discovered a problem in the new code we had implemented. Our method of creating an Event only created the first event that a character was associate with instead of all their events. We didn’t have enough time to fully work out the newly discovered issue and thus had to move forward with a code that wasn’t working to the full extent we were hoping for. This experience highlighted the importance of planning out a testing phase to strategically test for as many cases as possible.