Feature Debrief: Site-Wide Admin Flash Message
The Odin Project is a free online curriculum for learning web development with Ruby on Rails. It stitches together the best existing content into an opinionated and straightforward path for going from total novice to hireable as a junior developer.
Several students and interested parties have begun working together to help build the website and to get some real open source development experience. This feature is the first we produced.
Requirements
A “story” was created in Pivotal Tracker, which included the description and requirements of the feature we were going to build, acceptance criteria, mockups which illustrate the expected user interactions and a link to a google doc containing engineering notes.
The feature we were setting out to build had a few seemingly simple requirements:
The site owner needs to be able to create, update and delete a brief announcement that will be displayed at the top of every page on the website, except the home page.
The announcement needs to display for both users with accounts who are signed in and users without accounts (or are not signed in)
The announcement has a close button and once a user clicks the close button, it will slide up and no longer display for that user.
Collaborative environment
Our idea was to work in a pair programming style, but we had 4 or 5 people working at the same time…mob programming.
(Screen sharing misfire)
We started by setting up a workflow with SCRUM meetings and mob programming sessions using google hangouts, project management using PivotalTracker and google docs, version control with Git and Github and we coded together using nitrous.io.
Nitrous is a virtual real-time collaborative development environment. Everyone has their own cursor, so we can all see each other typing at the same time...Although, we quickly discovered that multiple people typing at the same time can become seriously confusing and dangerous.
Strategy
Our strategy was to create a model and database table to store admin flash messages and their expiration date. The site owner could add announcements by adding a new record to that table and the message would display until the expiration date, or until a user clicks it closed.
We knew that keeping the announcement closed for users who click the close button would require persistent storage. There was a lot of debate, but we moved forward with a vague plan involving cookies.
Goodbye, world! (Hello RSpec)
I forgot one last project requirement! Every aspect of this feature had to be written as a failing test before we could proceed to write our code. Once our code resulted in a successful test, we could then refactor to our hearts content, confident that if we break something, our tests would alert us right away.
Writing tests consumed our first programming session almost entirely. The sting was, during that first session, we only wrote three tests. Next, we created a model to store AdminFlash messages. We verified that the model worked with our tests and then we created some quick controller and view code to see the message displaying with our own eyes.
At this point, the adminFlash message was displaying, unstyled, on every page, without a way to deactivate it. And there it was. We had the most basic version of an admin flash message actually working.
Back to Pivotal tracker. What do we have to do next to complete this story? A lot.
We decided to style and position the message properly before moving on to the logic. Since the message was going to be displaying on every page, except the home page, we knew the application layout was going to house our message’s HTML. This involved working with a simple Bootstrap class and some investigation with Chrome developer tools to get the message properly integrated with the existing code.
To get the close button working on a purely visual level (without any persistence) we had to bind a jQuery function to the button, and call a slideUp() method on the buttons containing <div> element.
Next came what we thought was going to be the tricky part. When a user clicks the close button on an admin flash message, that message should close and never appear again for that user... whether they are logged in or not.
After hours of discussion and false starts, we realized that, since cookies live in the browser, we could simply create a cookie using javascript. No request to the server was necessary. The name of the cookie includes the adminFlash message id, and its expiration is set to the expiration date of the adminFlash message. You wouldn't believe how many complicated solutions we concocted before arriving at this simple solution!
The final piece of the puzzle was to make sure the adminFlash message didn't show again for users who had clicked the close button and created a cookie.
Another surprising decision was made. Instead of writing this logic in a controller, we created some methods in the AdminFlash model, and a view helper method.
The view helper collects all of the cookies from the browser using a regex based on our cookie naming convention. Then we call a model method from the view to retrieve all of the admin messages from the server that are not expired, and do not contain the same message id as the cookies that have been set.
Final Thoughts
The entire development process was broadcast live and unedited and archived on youtube. The idea behind this was to illustrate how the development process actually works including all of the technical errors, organization fumbles and googling for answers.
Being recorded live is definitely a humbling experience, but it definitely put the pressure on and forced me to give it my all. Which resulted in an unforgettable educational experience.
This post was written by Joshua Gorchov, a student of and contributor to The Odin Project [Editor's note: and generally awesome human]. Find him on Github here












