We were very excited when we found out we would get to sponsor this year's Rails Rumble competition, and are proud of all the great contestants and new apps that they've built using our favorite web framework!
There were a lot of entries, yet somehow I managed to look through them all on Sunday night. I was impressed with the problems many of the contestants were able to solve in just 48 hours, which makes me wonder what is possible for all of us in the coming year.
I also took some notes on a few glitches I ran into, and I thought it would be useful for all of us if I share them. So here goes:
Email address validation can be your enemy
tl:dr: Email addresses have complex formats. It's often easier to deal with a few malformed addresses rather than risk alienating a section of your customer base.
Like many other users, I like to keep track of emails from applications I'm evaluating. An easy way to do that is to append "+app_name" after the username of my email address, e.g., email@example.com. GMail in particular will still route those emails to my inbox, but I can use that tag to track spam back to the culprit, or filter out unwanted emails (sub-tip: always provide an opt-out feature.)
A problem I encountered on one RailsRumble entry - that I was particularly keen on test driving - was that when I entered my email address it wouldn't let me sign up, indicating that it was invalid. I quickly narrowed it down to the plus symbol, and after some internal debate over using my normal address or not, I closed the browser window.
The moral of this story is that email addresses are complex animals, and most regular expressions used to evaluate them are far from perfect. I'd rather loosely validate the email address (by asserting the presence of an @ symbol, for example) and deal with the few malformed addresses that get through than lose potential customers entirely.
Here's a less-stringent email regex that is included in the Devise initializer:
`# Email regex used to validate email formats. It simply asserts that # an one (and only one) @ exists in the given string. This is mainly # to give user feedback and not to assert the e-mail validity. /\A[^@]+@[^@]+\z/ `
Login with what?
tl:dr: I hate facebook, give me other options.
It's no secret among my friends and colleagues that I am not the biggest Facebook fan. So when an app requires me to have a Facebook account in order to use it, I'm clicking the "close" button on my browser tab, perhaps after a mournful sigh if the app looks particularly interesting/fun/useful.
It's too bad, because implementing a traditional email/password login option isn't that much extra work. If you're using OmniAuth for your Facebook integration, theDevise gem is a great addition to your Gemfile.
Building is just the start
tl:dr: Answer your customer support emails.
One of my favorite entries had an apparent bug that prevented me from logging in with Github. I was seriously excited to use this app, and I still am, because I haven't heard back from their customer support.
Here at Honeybadger, we do our best to maintain "inbox zero" in our Help Scoutaccount. That means replying to your emails (and fixing your problems) as soon as we see them come in. To do that, we make sure our entire team is getting notifications. Our favorite way to consume notifications is through our Campfire room, which is usually occupied by one or more of our team.
Monitor, monitor, monitor
tl:dr: Use Honeybadger :).
If you were starting a bakery, you would know immediately when a customer was banging on your front door because you forgot to unlock it. In the turbulent world of tech startups, however, you could lose thousands of customers before realizing something like over-ambitious email validation is preventing them from signing up.
That's why it's important to monitor everything. Here at Honeybadger, we utilize many internal and external services to keep tabs on the health and growth of our applications, and the lifecycle of our users. This issue is near and dear to our hearts, and is one of the reasons we built Honeybadger in the first place.