I have been working indirectly with Ruby on Rails for the past four years. I say indirectly as I have focused more on the UI side (views and sometimes the controllers) when it comes to working on projects. Typically, I work with another Rails developer who handles all the heavy lifting in the models and controllers. This time, I figured it was time to create a simple project on my own to feed the urge to program beyond my comfort level.
The spark
Talking with Paul Hepworth, the lead developer at Real Travel, instilled a challenge in myself. Normal workflow at Real Travel when it comes to Ruby development is I work on the views while Paul gets things setup in the models and controllers. Rarely I move past the view work as he is typically quicker on setting up the glue. Eventually, I want to gain more confidence in that area and be able to help out more on his end.
One of the projects in the queue for Real Travel is to integrate Twitter into our blogging system. On top of that, with the limitation of 140 characters per tweet, we would need our own short url service to keep our link weight instead of outsourcing to sites such as bit.ly. This is where I figured I would take charge and see if I could develop something that Real Travel could end up using.
Reverse engineering, sort of
After looking around at the services that currently offer URL shortening, I figured I would look to Bit.ly for inspiration and as a model on how its accomplished.
These services that have popped up all over the place due to the explosion of Twitter into the mainstream are nothing more than a basic look up table disguised by a semi-bookmarking system that redirect you to a URL you provide. Taking a long URL and condensing it depending on the number of URL’s previously shortened to about 1-8 characters after the name of the web server. For example:
1 | http://chrissloan.info/blog/sprites_a_not_just_a_css_fantasy/ |
2 | to |
3 | http://bitly.com/OVK02 |
So how does that long url get to be shortened? I knew it would be a basic incremented counter based off of the previous entered URL, but how would I get that character string? Not knowing a whole lot of Ruby methods, I figured I would start researching and initially came across the Ruby string method of
1 | .succ |
This seemed to do exactly what I wanted by incrementing whatever string I throw to it, except there was one problem. If I gave it a numerical string, such as “1” it would always increment numerically. If I gave it an alphabetical string, such as “a” it would always increment alphabetically. This was a problem because ultimately, it would limit the number of characters I would be allowed before the string got very long. I was looking for a solution that was alphanumeric — 0-9, a-z, A-Z. This would give me enough combinations of characters to keep the url’s short, 62x62x62…
I took a step back and knew that any database already increments the key id field, so there wasn’t any need to create my own special field. I could work off of this key id by converting it to Base62.
You are probably asking Base62? Don’t you mean, Base64? Well, sort of. Base64 is probably the best method and a true conversion number, but the last two numbers, no one can agree on. Ruby’s Base64 conversion throws in “=” signs for place holders and that didn’t look right and could pose problems down the line in URL handling. A quick Google search provided me with a base62 gem. I quickly installed it and it was exactly what I was looking for.
Programming hunger satisfied
After getting over the hump of figuring out how to shorten our URLs, in about 3 days I was able to create a simple Rails app including user authentication and tying it to Twitter. It felt good to be challenged and ultimately create a small simple app that will set the base for Real Travel’s Twitter integration.
Interested in trying out the app yourself and maybe building off it? Head on over to GitHub and download shortweet or clone it git://github.com/chrissloan/shortweet.git
Please be warned that it is very basic and surely can be cleaned up some. I didn’t spend any time on the UI, it is complete scaffold output. It is what it is.