Adding an “announcement bar” on the CodeNewbie homepage

Saron Yitbarek
6 min readJul 16, 2016

--

I squinted at the frozen papers, twisting into a spiral staircase floating on the screen. The angles weren’t quite right. They wrapped around the website’s title, light and warm, but it wasn’t quite right. I toyed with the transparency, made a few of the images smaller to give it depth. My scrunched forehead gave away my frustration, as I agonized over paper angles.

My team watched. Avi came to our group and looked over my shoulder. He smiled at my cartoon, amused. “That’s pretty close, but that piece of paper is too much like that other piece of paper,” he teased. “I’m just not sure it’s realistic enough.”

The paper cartoon I drew for our project web app.

My team laugh, and my forehead relaxed. We were a few days away from demoing our apps to potential employers, and paper angles were the least of our concerns.

I pride myself on being detail oriented on good days, and obsessed on others. As a journalist, that was a necessity. As a coder, not as much, especially when you’re still figuring out what details actually matter.

I think back to that moment often, when I find myself possessed by the details, drawn to the warm light of nailing every angle.

I thought about the moment again last night. I spent some time working on the announcement bar for the CodeNewbie site. It was late. I debated whether to go to bed or get it done. The answer was on the wallpaper of my computer. “No hesitations,” commanded the white letters, so I stopped thinking and started coding.

The goal was pretty simple. When we had a special announcement, contest, event, I wanted to display it on the home page. It would be a slim banner between the nav bar and the hero, noticeable but not distracting.

I started with a feature test.

require "spec_helper"feature "User sees an announcement banner" do
scenario "if there is an announcement" do
announcement = create(:announcement, active: true)
visit root_path expect(page).to have_content(announcement.body)
end
end

Note: To create my announcement in the spec, I’m using FactoryGirl.

I ran the spec, and it failed. It didn’t know what an :announcement was. This forced me to create an announcement, which meant writing a spec for it. I began writing the unit test:

require "spec_helper"describe Announcement do
describe "attributes" do

end
end

I had to think about its attributes. What is an announcement? I knew it would be made up of text and most likely a link. I could do both by having a body attribute where I’d save something like this:

Announcement.create(body: ‘Submit your design to our <a href=“#”>C odeNewbie Logo Contest</a> by 7/29!’)

And then I could use Rails’ .html_safe method to display it correctly. Genius! So I write this spec:

require "spec_helper"describe Announcement do
describe "attributes" do
it { should have_attribute(:body) }
end
end

Note: Here, I’m using Shoulda Matchers, from thoughtbot and is awesome.

But what happens when the announcement is over? How would I tell it that the contest passed?

It needed some sort of status. So I added an active attribute with a boolean. When I didn’t have an announcement, I would change the value to false, and it wouldn’t show. I added that spec:

require “spec_helper”describe Announcement do
describe “attributes” do
it { should have_attribute(:body) }
it { should have_attribute(:active) }
end
end

But what happens if I had multiple announcements with an active value of true? Would I have to make sure the other announcements were set to false? Or should I delete the announcement and make a new one each time? Do I want a record of all past announcements?

I asked Rob, going through the questions I asked myself and weighing the pros and cons of each. He frowned. “Just have one record and update it. What do you need to keep track of them for?” he said. “If you need it again, just retype it.”

I was doing that thing again, getting caught up in the angles, in the details that didn’t matter. In coding, those angles are all the different paths you could go down, the possible scenarios you might be in when using a feature, accounting for a future that has yet to be created. Dammit.

I thought about the most common use case for these announcements. I’d only use them when I had something to announce, which wasn’t very often. I thought about all the users who’d be creating announcements on the site. It was just me. I thought about how much time I wanted to spend on this feature. Not a lot. And with that, I decided to do the absolute bare minimum: I’d have one row at all times, and edit it when I needed. I wouldn’t even build any CRUD functionality for it, I’d just update it in the console when I needed to. And if that became too much of a hassle down the line, it would be addressed down the line.

And all of a sudden, I had a lot less work to do.

I ran my unit test, and was prompted to actually make an Announcement model. I made it:

rails g model announcement body:text active:boolean

I ran the migration, ran the spec again, and it passed. Then I climbed back up to the feature spec, where I had to adjust my test. I needed to test for two scenarios: 1) where there was an active announcement and 2) when the announcement was inactive.

require "spec_helper"feature "User sees an announcement banner" do
scenario "if there is an active announcement" do
announcement = create(:announcement, active: true)
visit root_path expect(page).to have_content(announcement.body)
end
scenario "but not if there is only an inactive announcement" do
announcement = create(:announcement, active: false)
visit root_path expect(page).not_to have_content(announcement.body)
end
end

Note: I’m not excited about the way these scenarios are written, but I haven’t quite figured out a less awkward way of saying it. Feel free to comment with ideas!

Then I ran the spec. This time, it failed because it didn’t see the content I was looking for. Progress! I went to the html page and decided to make the announcement a partial. In that _announcement.html.erb partial, I added the code that would display the announcement.

<% if @announcement %> 
<div class="announcement">
<%= @announcement.body.html_safe %>
</div>
<% end %>

Then I went to my controller and queried for that @announcement. I ran the spec again, and it passed. I wanted to try it out in the browser. I created an announcement in my local database, and loaded the page locally.

We’re getting there! But this needs some css love, badly. I added some styling to it, and voila!

I updated the active attribute to be false, and reloaded the page. It disappeared. Woohoo! I ran all my specs. They passed. I made a commit, merged, and pushed to staging.

I tried it out on our staging site. I made my announcement in the console and watched it appear on the site. I smiled, pleased with my little bar. But there was still a small part of me that felt like this feature incomplete, that the angles weren’t quite right, that I hadn’t accounted for all the details. I told that part to shut up, and pushed to production.

--

--

Saron Yitbarek

2x entrepreneur, founder of CodeNewbie (acquired), developer, speaker, podcast host, lover of all things startup