Hitting the ground running: A Python programmer builds a 1-day Rails 3.1 app
About 6 months ago, I moved from Pythonland to the “magic” of Rails land. I use quotes because I think Rails is “magic” in both good and bad ways. The last 6 months have been a bit of a programotional rollercoaster. I was neutral in the beginning until I discovered 1.month.ago. It was beautiful. The elegance of the Rails way over the Pythonic way was all I talked about for weeks.
But then I got bit by the drastically dynamic nature of Rails. Coming from Pythonland (and C before that, and Java before that), I had learned that you could always walk up a line of function calls and imports to determine what was being called and what was going on — until I found out with a kick to the pants about :after_create filters, and all their heathen brethren. I still don’t like them; I appreciate their power, but I think I think dynamic programming quickly makes for hard to follow code.
Then I started appreciating Rails for what it is: a language that’s optimized for programmer performance and not program execution time. It absolutely produces slow code, at the virtual machine level and in how libraries like ActiveRecord were implemented (FWIW, I think ORM is very hard and I do appreciate what ActiveRecord has done to make simple things quick and reliable).
When I began Rails, I had jumped right into a Rails project at a new job. I didn’t give myself a chance to try to learn the full stack because we use a moderately old version of Rails. I just dove in, asking when I couldn’t get things to work and asking for code reviews when I thought I had things working. As a result, I had never began a Rails project from scratch — only contributed to an existing codebase. I had bought just10cards.com on a whim a few months earlier, an idea to make a microsite that made it really quick and easy to create business cards, and the 6 hours I needed to kill before my flight seemed like a good opportunity to try building it in Rails.
Installing Rails.This was frustrating on my Macbook and only a little better on my Linux server. Ruby iterates a lot and quickly — which is great, but makes it really hard to keep compatible versions straight. The Ruby community responded with bundler to keep Gem files (packages) in sync and RVM (Ruby Version Manager) to keep Ruby versions in order. These are great tools, but I still think it’s an added layer of complexity to worry about. I had problems installing both RVM and bundler on my laptop (Ruby compilation issues, issues with bundler forgetting settings), and those are problems I never had with Python. However, I realize that I’m also new to these tools, and if I had as deep a knowledge in them as I did in git, I’m sure I’d just figure out the power of them and use them right. In any case, it’s still a little annoying to get a basic setup finished and working.
Building the app.This was fantastically quick and easy to build — I spent 2 hour and 4 hour sessions building and polishing my app. I didn’t end up using ActiveRecord at all; the site was a default controller (/) that requested (/cards) and passed data over GET. The CSS is actually a SASS template that gets compiled into a static asset, but CSS is perfectly valid SASS. CoffeeScript was different. I accidentally put JavaScript in there and it promptly yelled at me. Overall, I thought the entire static asset system was a little overkill. I appreciate what it can do for bigger sites, but adding a build step so early into a project’s life is a little cumbersome. script/generate is fantastic though, and templating is really where Rails can produce some very clean looking code. It’s so customized for web programming that most common actions are very terse. I still prefer Python as a general purpose language, but Ruby on Rails is a better solution for web development.
Deploying the app.One of the reasons I wanted to build this project was to play with Heroku for deploying apps. All of my previous side projects have suffered from screen purgatory, where they run in the foreground in a screen session on my server, and when they go down, I completely forget to bring them back up. Setting up Heroku was pretty straightforward, but required some fiddling to get Postgres support running go for production (a requirement for Heroku, but not something I was doing in development — I didn’t see any easy way to disable it completely). After some other initial frustrations (completely user error, and fully documented on their web site), I got my deployment working. And that was it; it’s just worked ever since. I know that’s a boring story, but that’s exactly what you want in a deployment process to a dedicated web server.
Watching the app.After building it, I “launched” it — I posted it to Twitter, Hacker News, and used $100 worth of Google AdWords (thank you free mailer from Google!). I had Google Analytics set up, but it was also nice to tail the log from Heroku to just get a feel for how busy the site was at its peak popularity. This would have been nicer had the log files been on a server I had ssh access to though; getting the logs from Heroku meant the overhead of starting Rails to get them (there’s probably a better way to do this, but this was the first solution I found when I Googled it).
Overall, I think building Rails projects and deploying to Heroku is a lot easier than working with something like Bottle for Python and deploying to Google App Engine. Python is great for a lot of things, including both web development and heavy data crunching — but Rails is great for web development. At my last job at a Python shop, we spent a lot of time discussing the merits of Python, its syntax, and how to correctly use it. At my current job, Rails makes it easy enough that those conversations aren’t worth having, and instead it gives us an opportunity to focus on code quality and improving the engineering process — which is a fantastic opportunity to have.