4 Things We Learnt In Our Week With Rails

Daniel Miller
march_18_acebook_jspesh
5 min readMay 17, 2018

Over the past week, myself, @Jordan, @Matthew & @Sam have been building a facebook clone to learn Ruby On Rails. We discuss some of the key things we learned about debugging using Rails, Heroku and Github.

Git Diff Before Committing

One of the great things about Ruby on Rails is that it auto-generates your models, views and controllers, the typical three-tier architecture for a web application. This offers a productivity boom. Rather than having to create an MVC framework for logging in users, establishing email authentication and encrypting passwords, you can simply install the Devise Gem. After, if you type in rails generate devise:install everything you need for login, sign-in and authentication is incorporated into your app.

One of the problems with all this new functionality is the increased complexity of your file and folder structure. There are dependencies between your files and folders which aren’t always explicit. When problems and bugs emerge, it can be difficult to identify the source of the problem because you will be making small and incremental changes across multiple files.

A typical Rails project directory

Keeping track of the changes can be difficult. However, by calling git diff you can see the difference between files across commits. This allows you to focus on the changes that have been implemented across your codebase, and zone in on the potential source of the problem. Some text editors, such as Visual Code even include a visual tool for viewing changes before you commit them. This allows you to review all changes across files, and ensure you don’t implement features or call libraries that could potentially break functionality in other files.

binding.pry will pause execution of code and give you a window into it to explore

We learnt about this problem by including a debugging library that was available in our development environment, but not in our production environment. When we ran the application in production, this one line crashed the app as it was unable to load the library. Unable to determine from the error provided what was causing the crash we used Git Diff. By using Git Diff, this entire problem could have been avoided as we would have spotted a debugging line that we forgot to remove.

Reading error messages and following how your application executes code is essential for effective debugging. Only by following the ‘stack trace’ (the history of executed code) can you identify where bugs and errors emerge. If, for example a user goes to log in but only an error message is generated, this could be caused by a multitude of reasons. The stack trace will reveal the source of the bug. Is the database configured to accept the users credentials correctly? It could also be an issue with passing parameters from the web-page(view) to the model. The stack trace allows you to identify the file that holds the error, and the line that is causing the error. From here you can begin investigating the causes, and the solutions to programming bug.

Heroku generates a stack trace throughout your application. The stack trace is not intuitive though, as can be seen below:

Heroku stack trace

As you can see, the colours do not represent whether code is being executed successfully, as it would if you were using a gem such as RSpec. Blue lines show the files that are executed or rendered and database requests that the app utilises. Orange lines reveal the routes that are followed and the status of get/post requests. To make things more complicated, the colours will change if you refresh the page or launch a new build!

It is intuitive for humans to associate the colour green with success, and red with errors. In Heroku, error messages are shown in the exact same format as all other messages. They are not highlighted, coloured or bold. They appear in the exact same format as regular code, and it’s very likely that an error message will be green. Because of this, the stack trace in Heroku needs to be read with precision and care, otherwise you will miss the source of the error.

We learnt this through the identification of the misplaced call to the Pry Library. The error message appeared on an innocuous green line. We missed the line several times until we dropped the assumption that colours represented success and failure throughout the code. Upon identifying the error, the bug was relatively easy to fix. We feel that the experience has improved our ability to read and interpret error messages, and demonstrates the importance of approaching debugging with as few assumptions about how things should work as possible.

Cover Edge Cases and Unhappy Paths with Feature Tests

Continuing the trend for this post we have another moment where failing to follow best practices slowed us down and made our development cycle unnecessarily painful. Again, the solution to our problem is not complex, yet the small details are easy to miss from time to time, especially when dealing with a new technology which introduces many new things to keep track of. When testing our authentication system we wrote a number of feature tests to verify that a user could sign-up, login, logout and navigate through the pages of our site.

As we were using devise for authentication, a highly reliable and tested gem, it seemed as though minimal testing was needed. We assumed that the tests that we had would be enough to alert us to any problems that may arise with our authentication system, such as if we had a problem with our database or our configuration of devise. Later on in the project, while writing a test for a different feature, we had to spend a small period of time debugging an initially confusing problem where we were unable to setup a test as intended.

When we found the cause of the issue and decided to discuss how we could have avoided causing this problem in the first place, we found that thorough testing of edge cases and unhappy paths would have alerted us to the issue before it became a problem that slowed our workflow down. You may have tested that your users can login and logout, but have you tested what happens when a logged in user visits the login page? It is very easy to overlook unhappy paths like these, allowing your users to interact with your site in unintended ways.

It may seem tedious and difficult, but it really is necessary to spend time thinking about edge cases and unhappy paths through your applications, and then writing tests to cover these situations. Doing this will give you a greater understanding of the architecture of your application, whilst also alerting you to many potential issues before they become problems, saving you from pain in the long run.

--

--

Daniel Miller
march_18_acebook_jspesh

Contract lead machine learning engineer. Sharing what I learn along the way.