Wednesday, June 18, 2008

Lessons from my first Rails project

I’m finally being paid for working on an “Enterprise” Ruby on Rails pilot project. I think I helped persuade our IT group to give Rails a try. But unfortunately I wasn’t available to help the project get started. Instead I joined the project several months in. So while it’s cool to finally be doing Ruby and Rails full-time it’s also pretty painful to be living with some of the poor decisions made before I got here. I can’t say that if I’d been involved from the get-go that we would have avoided some of these problems (sometimes it runs deeper than the technology) but what I can offer is a list of things I’d suggest you watch out for (in no particular order):

Be realistic
In the early days of Rails I remember people saying things that made it sound that Rails was ten times more productive than Java. That’s a wild exaggeration and everybody should know it. There’s no way you’re going to be 10X more productive, end of story. Hope for “10% more productive” after you’ve got one or two projects under your belt. At least that’s realistic and achievable and if you get more than that then great! But for the love of God don’t start off with that idea. A big part of the software game is managing expectations. Don’t dig yourself a hole you have to try and climb out of. Despite what you read on the web, your first Rails project will probably take you more time, not less. New language, new tools, new framework, new infrastructure, new bugs, and new deployment problems. My project started with unrealistic expectations and now we’re over budget and over schedule. That’s not a great way to get management on your side.

Deploy early and often
That’s an agile thing and not unique to Rails, but getting over the hurdles of deployment shouldn’t be taken for granted. We’re primarily a Java shop so when people saw JRuby and WAR deployment, they figured everything would be easy-peasy. Not so. Part of being “Enterprise” is that quite often you’re several months, if not years, behind the technical curve. The first thing we needed was to get past Java 1.4 and an old version of Weblogic. We needed at least Java 6 and Tomcat 6. Trust me, getting “comfortable” IT infrastructure people to upgrade their technology can be very painful and slow.

Now assuming you got the basic app server running on a reasonably recent version of Java, go and figure out how to build the WAR (warbler gem), get to Oracle (activerecord-jdbc gem) through JNDI, get your Rails log files out of the exploded war directory (logging gem), integrate with ActiveDirectory for Authentication and you’ve got your hands full of a bunch of other problems that will eat away at your time. Budget for it.

Now once you got all that, deploy often! Our project has periodically deployed something outside of our dev environment but not frequently enough to gather any kind of momentum to satisfy our users. Without gaining the users’ trust you get into a whole other set of problems.

Unit test (RSpec seems pretty awesome)
Sounds like a reasonable thing to do... but we didn’t. I won’t go into all the reasons why testing is good, but to fail to take advantage of the testing infrastructure that Rails gives you out of the box is pretty ridiculous. Even if all you’re doing is executing the code and never asserting the results are correct at least you’re executing the code and will find runtime problems that a language like Java would have given you at compile time. I started using RSpec for my stuff and I really like it, but it sucks when the other developers won’t add to the tests or even run yours. But my strategy is to lead by example. Maybe sooner or later the other will pick it up too. If you can get buy-in early and be ruthless about keeping your testing effort on track.

Figure out the non-standard Rails stuff
Beyond the deployment stuff I talked about earlier, figure out the other places you must configure rather than adopting the Rails conventions. For example, we have a rule that says you must access the database from an account other than the schema owner. That means we needed to call set_table_name(‘schema.table’) in all of our models. We also needed to create the permissions for the non-schema owner. And don’t forget proper referential integrity constraints in your migrations. These are all things you can ignore for a while but if you have any hope of putting you application in your users’ hands you’re going to have to figure it out. Personally, I hate surprises like this late in the project. My recommendation is to sort them out early.

Don’t underestimate security (a.k.a., read the requirements doc)
We have users who don’t trust anyone and have dreamed up one of the most elaborate security mechanisms you can think of. Unfortunately we went through five months of development and not one of the developers before me even seriously looked at it. Sadly, I can understand why. Every Java developer (including me) thinks they got that one figured out and just skips that part of the requirements doc. Except that someone should have actually read ours and said Woah! It’s not always easy to retrofit something like this if you just assumed it was an orthogonal concern. If someone wrote a requirements document for you (no matter how badly written) be sure to read through the whole thing. You never know what problems may be lurking.

Read ‘The Rails Way’
In general, get some training. Or in lieu of that, get some good books. I bought “The Rails Way” by Obie Fernandez (great book btw) after I got assigned to the project. To my way of thinking the project should have already bought a whole bunch of Rails books and made them available to the developers. But it’s up to you to be prepared. If there are parts of the framework that are still a bit fuzzy start reading some books (go to the source if you need to).

Evaluate your editor
So like I said before, our shop is primarily a Java shop, so when I got on the project people were using IntelliJ to edit their code. Now IntelliJ may be a kick-ass Java IDE but from what I’ve seen it’s not great for doing Rails. So when I started, I used NetBeans. Now NetBeans has never in my mind been a great Java IDE, and quite frankly it’s not my dream Ruby IDE either but Sun hired the JRuby dudes and Tor Norbye, the principal NetBeans guy at Sun seems to understand Ruby and the needs of Rails developers pretty well. As near as I can tell, unless your a Mac-toting Textmate user, NetBeans is the best game in town for Rails development (I even use it on my Mac). So my recommendations is to get off your butt and seriously evaluate the tools you’re using. Maybe IntelliJ is the right thing for you, but you don’t really know unless you look around.

Use an issue tracking system
We didn’t have an issue tracking system when I started on this project. So not only could we not tell how far we were by test/spec status, we weren’t even tracking the change requests and bugs properly. Wow. In my mind this is part of the scope problem we’re having. The users just ask for something and without visibility to the whole team and management, it just gets magically added and the schedule slips.

Web 1.0
AJAX is pretty attractive to a Web 1.0 developer. But food is awfully attractive to a starving man too, but that doesn’t mean you should let him eat himself to death. Take it slowly. IMHO, do it old school on your first (and maybe your second or third) Rails project. Throw in the odd autocompleting field if you want but this AJAX stuff and all the pretty visual effects can get out of hand pretty quickly.

Use people who want it to succeed
Java and .NET are pretty typical technologies in IT and unfortunately a lot of the developers who’ve invested a lot of time learning this stuff seem to forget that the technology is only a means to an end and not the end itself. They’ll be threatened by new technology. They’ll be threatened by Ruby and Rails. So if you can, staff your project with the developers who are open minded and wouldn’t mind if a Rails application succeeded. If you push these hostile developers onto a Rails project their negativity will bring everyone else down.

Understand RESTful Rails
I don’t remember when exactly David Heinemeier Hansson really started pushing the idea of a resourceful/RESTful way to develop web applications with Rails, but it’s damn good stuff and you should really figure out what it all means before you start building a whole bunch of stuff the old way. Figure out Rails’ routing system and what map.resources does and then you’ll be able to go with the flow and let Rails do a lot more of the work for you. I’ve seen more than one developer write a lot more code than they need to.

Separate HTML, CSS, & Javascript
I can’t believe these so called IT web developers who still use all the old FONT, BORDER, WIDTH, ONCLICK etc. HTML elements in their templates. C’mon! HTML is mark-up, CSS is styling and JS is behaviour. Separate these aspects of your view layer the same way you separate models, views, and controllers. I’ll make some allowances for surgical uses of RJS but if you want things to be maintainable sort this out already. (I know this isn’t just about Rails but it bugs me so much I figured I’d rant about it anyway ;-))

If you’re about to embark on a Rails project, get ready to enjoy yourself, just don’t lose your head in all the hype and follow some good common sense.