All Aboard the Rails Train

Kunal Shah
7 min readFeb 5, 2021

--

The time at Flatiron School is flying by and I cannot believe I just completed my third project, a Ruby on Rails web application. I wanted to share a little bit about my project, parts of the process that helped me succeed, and some challenges I faced during it.

For my project, I have an interest in the stock market and investing. From what I have seen, people tend to have many different investment accounts from a brokerage account, IRA, 401K, etc. Moreover, all those accounts are on different platforms as well. So I decided to create a web application where you could see all your portfolios in one place as well as keep watchlists of stocks as well. And thus, Stock Tracker was born (yes, I do need to work on my title creativity).

I am a big planner/organizer, so as with my other projects before I got to actually coding, I took a few hours to actually plan out exactly how my project would function from: the models, the model attributes, the associations between the models, routes I would need, view pages for each resource and more.

#Issue 1

I knew that I would need an API so that I could pull in stock information. However, as I did my research online, it seemed that the big free APIs like Google Finance and Yahoo Finance were shut down in the past couple of years. Eventually, I found my initial API (more issues with this later). During this planning process, I wanted to have a stock model, so that a User’s portfolios and watchlists could have many stocks, but I didn’t want a user to have to “create” stocks because then my database would have so many repeating stocks. Instead, I found a separate, recently updated API that let me pull in basic stock information of name, symbol, and sector for the S&P 500, which contains almost every big stock. Then, I would seed my database with those stocks, enabling me to have all stocks available to all users. Plus, I did not want a user to be able to change a stock’s attributes, so I did not keep the normal CRUD actions for stocks either.

Setting Up Associations and Routes — The Planning

Now that I knew where I would be getting my stock attributes and stock data from, I began to write out exactly how my models in my project would connect together. For this project, Flatiron gave us some specific technical requirements they wanted like multiple has-many relationships and a joins-table that takes in user-provided attributes. Mapping out my models, I ended up with a User, Portfolio, Watchlist, and Stock model. I was struggling for a while with how to include a joins-table that would take in user input. Finally, I had a “Duh!” moment because the answer was just under my nose. In a portfolio, a user is going to want to show a stock, how much of it they own and how much it costs. Since I had a stock model, I could connect portfolios and stocks in a many-to-many relationship with the connecting joins-table being a “Stock Purchase.” A stock-purchase belongs to a stock and a portfolio and it would take in things like shares purchased and how much each share cost. With the power of Active Record, these stock-purchases would automatically be linked to a stock and a portfolio. Using this joins-table also allowed my stock instances to be constantly reissued and not beholden to a single portfolio.

After I wrote out all my associations, I then tackled my routes aka what are the URLs a user of the app would access. I needed to make sure I followed the RESTful architectural style, but I also wanted them to look “aesthetically” correct from a user experience. I typed out each route that a user may access on the site and associated it with the controller action it would go to. This involved me determining which routes would be nested, which did not need to be, and which needed to be aliased.

By writing out my models, associations, and routes, I also figured out my controller actions and views pages. This saved me so much time with coding! I created a new Rails project and within a half-hour, I had generated all my migrations, tables, models, controllers, and routes and I was able to easily wire up all my model associations. I went into my console to test out the associations. Seeing them all working, I won’t lie, I jumped out of my chair and did a little dance.

(Pro-Tip: if you use `rails c -s` it creates a sandbox environment and nothing will save to your database)

I was excited because I felt this was the much more important and harder part of the project. Now I just had to actually display the information via controller actions and view pages while using partials and helpers to keep my code DRY and clean looking. The second part took more time because it’s simply just more code to write out and trying to figure out exactly what I want to be displayed on each page.

Bootstrap

I want to give a quick shoutout for Bootstrap. Coming from my Sinatra project where I wrote out all my own CSS, I did not want to do that again. Incorporating Bootstrap into my project made using CSS so much easier. While my code looks a bit more cluttered (so many classes used), it was much easier to use CSS by just following the Bootstrap documentation.

Issue # 2 — API Requests

So after building out my project and getting my views pages up and running, I was looking at a stock’s show page to see the data come through. But I ran into a problem; I was getting a weird error that it couldn’t the data I was requesting. I went back to the parsed JSON and checked that I was correctly extracting the information. I then removed the piece of data that was giving me an error and refreshed it. Then the data showed up. I refreshed again, and got the same error! I was frustrated because it literally showed that data and upon refresh it’s telling me it’s no longer working. I went back to my API’s documentation to ensure I was correctly calling the API. As I read through, I found a section stating that the free version of the API only allowed 5 requests per minute.

Well, there was the source of my problem! I was making too many requests and thus I was not getting the data. My code at the time was making more than 5 API requests per stock. I rewrote my code so that in 1 API request I would collect all the information I needed for that stock. Now, when I went to a stock’s show page, I could see all the information without getting the error. I thought I was in the clear until I got to my watchlist’s page. I quickly found out that while I cut down on the requests per stock, if a watchlist had more than 5 stocks in it, I would get the same error. So while my app was functional, it was limiting because a user could not have more than 5 stocks in a watchlist. Plus, say you removed a stock, and the page refreshed, you would get the same error because even though there are only 4 stocks on the page, I actually made 9 API requests within that minute. Thankfully, after doing some more searching, I was able to find another API that managed their requests amount solely by monthly usage and I wouldn’t have to limit the number of stocks a user could add to their portfolios and watchlists.

OmniAuth

A cool feature that was required in this project was offering a 3rd Party login option. In Rails, we use a gem called OmniAuth that enables us to use other sites like Facebook, Github, Google, and many more to log in to your web app. It eliminates needing to be able to handle password changes, email verification, and password recovery. While Rails secures passwords, it is not securing the server. Thus, someone could hack into the server and cause havoc. By using these 3rd party partners (called strategies), you basically say goodbye to this problem.

I have to say it definitely made my web app feel more real because 3rd party authentication is so common on websites now.

Coming from Sinatra, I really was able to appreciate how much Rails handles for the developer. I did not touch on them in this post, but things like validations, partials, and scope methods that I included in my project were made so easy by Rails. For instance, I did not have to create my own method to validate if a user has entered a password with the correct length, Rails can do that for me. All I have to do is type in one line of code and boom, it’s done! You can check out the validations, partials, and scope methods I used in my repo linked below. I feel really proud of the website I built and feeling more confident in my growing coding abilities.

Takeaways

  • Draw out your models and associations; it helps to visualize your application on paper before starting to code
  • Documentation is your best friend. Googling works, but always check the original documentation first; I solved many issues just using Rails Documentation and API
  • When dealing with API requests, extract as much information from one request to reduce the number of requests made
  • Use a front-end framework to make styling your website easier with their pre-built CSS classes

If you want to see the app or code, check out my repo here.

The Journey Continues!

--

--

Kunal Shah
Kunal Shah

Written by Kunal Shah

Full Stack Web Developer | Flatiron School Software Engineering Graduate | TV Show Enthusiast. Pittsburgh Sports Fanatic.

No responses yet