My experience with Ruby on Rails
Background
I first started playing with Rails around version one, working through the Depot application in the first edition of Agile Web Development with Rails. However, at the time the complexities of deploying a Rails app, combined with the prevalence of PHP as an easy-to-deploy, easy-to-understand web technology lured me away.
After starting at my current position in 2007, I was looking for an elegant alternative to their ASP .NET platform and settled on Django for personal and freelance work. Django was fantastic for whipping up sites with managed content, blogs, and so forth, but it was very difficult to iterate on (lacking built-in migrations), and again, difficult to deploy, requiring a Slicehost VPS for only a handful of sites with limited traffic.
Initial thoughts
Re-exposed to Ruby and Rails in the summer of 2010, I took to it quickly. Several things stood out:
- Haml and Sass are amazingly terse, powerful tools for front-end development. I feel like writing raw HTML and CSS is slow and bloated by comparison.
- Rails is very condusive to elegant front-end development in general, with incredibly useful helpers out of the box, plus great gems for speeding build (Formtastic) or managing assets (Jammit)
- Migrations reduce the speedbumps in developing features iteratively (without a long planning phase) significantly.
- A lot of the ecosystem of tools around Rails and Ruby are slick and mature, like RVM, Bundler, and Heroku's command-line app.
- Rack was sorely missed when I first started playing with Rails in 2007. The simplicity of middleware like rewrites, manipulating requests and response, etc, are incredibly useful. It's a huge boon that other frameworks besides Rails (like Sinatra) can also sit on top of Rack.
- Heroku is just amazing for easy deployment and maintenance. I'll never go back, even though the read-only filesystem does present some challenges.
Summer 2010 - Beyond Grammar
My first project in Ruby was rebuilding a simple client site, Beyond Grammar. Originally built on Django, Beyond Grammar was a collection of static pages written in Markdown with a contact form. Django made this easy, but at the same time felt like hitting a thumbtack with a sledgehammer, requiring VPS hosting for what was virtually a brochure site.
I rebuilt the Beyond Grammar site using Sinatra in the summer of 2010, choosing Sinatra because of the simplicity of the framework, so as to help isolate learning Ruby, and learning Rails, into two different tasks.
Sinatra's limited level of abstraction coupled with my familiarity with the technologies of the web made Beyond Grammar an easy build. I wrote some utilty functions and helpers that would look in a folder of markdown files, and, using the names of each file (humanized), created a clean URL structure of static pages.
The only irritating part was handling the contact form in Sinatra, because there was nothing to speed up the process. Storing all the post data, redisplaying it in the form if there were errors, or creating a "flash" message for success added up to be a bit of a pain.
You will find extensive Test::Unit tests for Beyond Grammar - once of my first serious exposures to unit-testing. I couldn't quite get my head around TDD for this project, but I did attempt a high level of test coverage.
Overall, if I were to build Beyond Grammar now, I'd build it in Rails to ease some of these pain-points, and make it much easier to add new features, especially database-driven features.
The source code for Beyond Grammar is available at Github. You can also check out my portfolio page.
Fall/Winter 2010 - Portfolio site
Like Beyond Grammar, my original portfolio site was also built on Django as a platform. Overall, I had few complaints with Django, other than the lack of migrations made any new feature require a lot of mucking around in the database. I also had some problems with Django deployment, always trying to get the settings right to ensure the site went up and stayed up with no maintenance required.
My new portfolio site (what you're reading right now) is a fairly ambitious plunge into Rails. I used Rails 3 and Ruby 1.9, trying to get out in front of as much new technology as possible. Rails 3 really agreed with me, and I'm glad I went for it, originally starting with a release candidate and upgrading as I went.
My biggest challenge with my site was choosing how to handle the admin tool. After experimenting with rails_admin and Typus, I ended up rolling my own using inherited_resources to avoid writing a bunch of boilerplate CRUD controller code, and Formtastic to simplify form building hugely.
I anticipated a challenge with the read-only filesystem, but Paperclip's S3 mode was seamless. It took me about an hour to get it sorted out and configured.
Much of the content on the site is as simple as it gets, displaying a list of active Post or Work objects, or using high_voltage to display static pages.
One place things did get a bit more complex was displaying my footer content, variously sourced from Twitter, Pinboard, and Github JSON feeds. I used HTTParty to simplify things a bit, and set up a cron job to consume data from each of those services and store them in the local DB.
Another fairly complex piece was the Contact page - not wanting to give up Formtastic I built an ActiveModel (not bound to a database) to store the contact information, to aid in validation and form building. That model information then gets passed to an ActionMailer and uses Heroku's excellent Sendgrid add-on.
Also worth noting is the front-end, where I used Haml and Sass as well as some custom helpers. Haml especially made my life much easier. I haven't required any JavaScript functionality on the site yet, but when I do I'll definitely reach for CoffeeScript, although I'm anticipating some trouble integrating it with Heroku's read-only filesystem. Maybe once they offer node.js hosting? Site note: I also took advantage of the straightforward layout to use 960.gs - the amount of custom CSS coding required at my agency day job had me looking for a way to really speed up the process, and it certainly did.
Performance was a concern for my site, as I want to maximize the power supplied by the 1-2 dynos I'm leveraging on Heroku. Heroku, using Varnish, allows for setting the Cache-Control header to send purely static pages (of everything but the contact form) to users. Every 15 minutes (or after a deployment) those cached files are updated, and the performance boost is visible.
Although I tried to learn the Rails stack alongside Rspec and Cucumber, it ended up being too much to take on at one time. I compromised by using Shoulda to speed up my testing, and although I could stand to have some integration and view tests especially, I learned a lot about testing during this site build.
The source code is available at Github.