« March 2006 | Main | May 2006 »

April 24, 2006

The Days I Turned Pluralisations: Off

Listen to this articleListen to this article

Oh what a day it was.

You see, the first real Rails project we did, I thought, "well, I'll give it a try. This guy seems to know what he's talkign about and even though pluralisation goes against everything I've ever learned or studied with repsect to database design, why not?"

One of the major factors in making rails so productive (for me at least) is that it reduces the cognitive dissonance—between my ideas (creativity) and the implementation (ruby/rails). I find when I'm coding in rails that it's enabling me to quite literally code what I'm thinking as I'm creating, in way that Java never has. (That's not necessarily the fault of Java per-se, rather my feeble brain.) The pluralisation stuff seems to fly directly in the face of this.

Well suffice to say that on my second real project, I decided to turn it off, and my brain thanked me for it. I simply added the following to config/environment.rb:

Rails::Initializer.run do |config|
  ...
  config.active_record.pluralize_table_names = false
end

No longer did I need to keep remembering that even though the class is called Entity the table is called Entities. No more pissing around with pluralisation rules because, what-do-you-know, the default ones can't handle the fact that the plural of UnitOfMeasure is unitS_of_measure. No more switching contexts everytime I go from SQL to Ruby code. (Yes, I manually dig around in the database using SQL to make sure I haven't screwed something up. And yes, I also use the rails console.)

And you know what? In neither project has the customer once asked me to show them the database schema—one of the arguments supposedly for using plural table names. No, in fact if I ever wanted to show the customer anything (other than the application itself), I usually scribbled labelled boxes on a whiteboard and even then, I've not once had anyone give me a puzzled look or ask "why is that singular?" Strange perhaps but true!

So whilst I admire the audacity and coding athleticisim of DHH for creating the pluralisation code, I'm far more impressed with the work he and the team have done on Rails 1.1. Everything seems so much "better": ActiveRecord for one; and especially RJS templates as another example. At least they had the foresight (even pre 1.0) to allow pluralisation to be turned off!

Halleloujah!

April 18, 2006

Real-estate on Rails

Listen to this articleListen to this article

Our first Ruby on Rails application finally went live...almost. Having never even looked at Ruby, let-alone Rails, before embarking on the project, it's been a huge learning experience curve but certainly one worth having.

The site is, as you may have guessed it, a Real-Estate web site for Bowral (and surrounds) in New South Wales—I don't actually know where that is. The original spec was somewhat of a Design-by-Quark-Express™ and although it was excruciantingly precise on look, lacked a little on functionality.

The result is not too bad for a first go—a spike as James keeps re-assuring me. It's all very Web 2.0ish with its 800x600 borders and AJAX forms, etc. It has scrolling images, dynamic content and layout here and there, server-side emailing and even an RSS feed or two just for fun. Most of it looks great in all major browsers but sometimes we did have to compromise in favour of Internet Explodrer.

Rails really is a lot of fun to work with, most of the time—indeed the hardest part of the application, besides learning RoR, was the HTML+CSS. The bits that work well, work really, really well: views, routing, configuration, database connections, migrations, plugins, etc. The bits that didn't work so well were the mailer stuff and, sadly, active record.

The mailer stuff smacks of J2EE: layer, upon layer, upon layer. They got some bits right: emails are essential views just like their HTML counterparts. Unfortunately though, the mailer itself (and consequently the email templates) doesn't have access to all the cool controller/helper functionality meaning you end up doing a lot of redundant stuff in a controller just so you can send URL's etc. in emails.

And the of course there's active record which, I must admit, works wonders for the most part. Single-table inheritence sux big fat wobbly things that don't fit down your gullet and thus nearly choke you to death before you manage to cough them up. In the end we implemented an acts_as_subclass_of plugin that assumes you have two tables sharing a primary key. Silently failing saves on relationships aren't much fun either. And I have to say that making transaction a part of a record is kinda dumb. The two things have little to do with one another and arbitrarily choosing to use one class over another when updating multiple records seems so un-railsy. Ok so now I'm being petty but it does irk me that they didn't get absolutely EVERYTHING right ;-)

Caching has it's issues as well but we worked around most of the limitations for our needs and it's working a treat. We essentially have pretty close to a fully on-demand website—include images—generated from a PostgreSQL database. As parts of the site are accessed, the results are cached, eventually resulting in an almost entirely static website. This "warming up" process could easily be automated on deployment.

We really only used two third-party plugins: enumerations; and verbose migrations though we tried a few more but didn't really see the need in the context of this particular application.

Oh yeah, we're using SwitchTowerCapistrano making deployment a breeze. Except for the fact that, for some reason, lighttpd doesn't seem to like being re-started from within the script. Not really a problem as the site needs to migrate to Apache 2.0 + FCGI sometime soon anyway to fit in with the customer's site management tools but annoying.

Database migrations work fairly well as long as you don't change your model too much. Pretty much anytime you delete a model class, you need to make a copy of it inside your migration script(s) so they can use it if/when you deploy a brand new application. Somewhat annoying to say the least but I don't have a better solution, save laboriously checking out each successive "version" of the application one at a time and running migrate. Suggestions anyone?

Still on the database front, I also patched some of the PostgreSQL driver code to fix some bugs (I think I reported them) and to add in missing features such as foreign-key constraints, column check constraints and VACUUM. I know everyone loves MySQL and you're all probably aware that I don't but, prejudices aside, you have to love a database that allows you to back-up using:

$ pg_dump -o -O cjp_production | gzip > cjp_production.gz

Development was done (for the most part) using TextMate+Subversion on our lovely PowerBooks (yes, we're so December 2005) and deployed to a FreeBSD box which, I have to say has a very nice package management system. (I always liked FreeBSD back in the version 2/3 days and I like it even more now. It certainly feels like a great platform for production environments.) Virtual PC also came in very handy as for running Windoze in order to test the site.

I think I only used rails' generate script once to see what it would produce—lot's of noise—after which I chose to hand-cruft my code. I suspect I'm a control-freak at heart ;-).

The real winner for me though is Ruby. It's just nice. It too has it's foibles but I really do find I write less verbose (and certainly less syntactic) code. It has already started to change the way I think about code and I like where I'm headed. It'll be interesting to see how much it screws up my Java code ;-)

All-in all an very pleasant experience. I'm not a huge fan of web apps in general but Rails certainly makes them much more fun and the rise of DHTML for client-side processing definitely makes for far more interesting client-side applications. I could certainly enjoy making a living this way.

So, anyway, if you've ever been interested in owning a property with your own 2-acres of truffles, I know just the place ;-)