avatarharuki zaemon

Real-estate on Rails

By

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 ;-)

Simply Delicious

By

Like just about everyone these days, I have a Delicious account. (For those of you still living in early 2005, it’s a social bookmarking site.) I use it whenever I have a link to something that I want to remember personally and also for links that I would have blogged about but for which I don’t feel a blog is really the appropriate medium.

One feature I love about deli.cio.us (yes that is the correct spelling) is the inbox. If you haven’t looked at it, it’s a great way to keep track of other peoples bookmarks. So, rather than subscribe to individual bookmark feeds, you can instead add each feed to your inbox and then subscibe to your own inbox. This way you get all the feeds in one shot and it also lets others see what bookmarks you are interested in.

So, if you’re remotely interested in checking out things that I’m interested in or things I think you might be interested, it’s easy to subscribe to my own links or even subscribe to my inbox to see links other people have that interest me.

Aussie, Aussie, Aussie. Oi Oi Oi.

By

If you live in Australia, and Melbourne in particular, it would be hard not to notice that the Commonwealth Games have been underway for a little over a week now. (If you’ve never heard of the Commonwealth Games then you’re probably not from a former British colony. It’s somewhat like the Olympics but without all those pesky countries such as the USA, Russia and China to make us feel inadequate.)

Anyway, living in Melbourne as I do, it’s hard not to be overwhelmed by the media coverage here and the constant whir of helicopters overhead, no doubt protecting us from all those nasty would-be terrorists that somehow think it’s worth attacking a country that is 85% uninhabitable, in constant drought and has nothing much to offer (according to our media) besides sport.

Australia, it seems, fairs pretty well in the ‘Games. At last tally we had close to double the number of medals of the nearest competitor – Hardly surprising considering we’re second only to the US in terms of public dollars spent on sports.

However, all that money seems a little wasted really. Not because I don’t think sports are important for the health of the nation but because if you were to actually sit and watch any of the television coverage, or read anything in the print media, you’d soon start to wonder if there are actually any other nations competing.

I’ve looked long and hard. I’ve watched every television channel and read evey newspaper I could find but try as I might, I get the distinct impression that the only people competing are from Australia. Indeed in some events, I’m not actually sure what the rules are as no one appears to win a gold medal – the whole point I would have thought. For some strange reason, the only apparent competiror in the race (an Australian do less) somehow had to “make do” with a Silver medal or stranger still, receive no medal at all even though they ran a personal best time.

I know for a fact there are other competitors from other nations here in Melbourne (I presume for the purpose of competing) but besides those named as missing – possibly seeking political asylum – I’m yet to actually see any compete or win medals.

Perhaps I need to go and see an actual event live and have a look for myself? Then again, maybe I’ll stay at home instead and let all those fantastic images of Australians doing so well allow me to forget for a moment the fact that we spend more on our sporting elite than we do on health for the average citizen.

Writing Under a Doppleganger

By

Apparently a little more than just the text of James’ and my book was translated for the GermanDutch market.

So, I couldn’t help myself…apparently you don’t even have to be translated to be given a pseudonym.

eBay Schmeebay

By

So Phil asks me why I haven’t blogged in so long. The quick answer is: I haven’t had anything much to enrage me recently and consequently I haven’t had much if anything to blog about. (It’s amazing what time away from a computer does for ones mental health.)

The I receive this email:

Dear eBay Member: kwikdigital has informed us that they have not yet received your payment for the following item:CANON IR 8500 w/ NetworkPrinter +K3N FINISHER 85PPM - (#7557660205) No action is being taken against your account at this time. However, it is important to remember that when you bid on or buy an item you are agreeing to a contract between you and the seller. If the situation isn't resolved within 7 days of this reminder, you may receive an Unpaid Item strike under eBay's Unpaid Item Policy. If you don't respond by Mar-03-2006 you may receive an Unpaid Item strike. Most Unpaid Item disputes can be resolved through direct communication between the buyer and seller, and we encourage you to work with your trading partner to reach a resolution. Regards, eBay

Only I’m not an eBay member; never have been; don’t seem myself ever becoming one. So I do the “right” thing and forward it to abuse@ebay.com and for my efforts I receive another email:

Thank you for writing to the eBay SafeHarbor Team. The address you wrote to (safeharbor@ebay.com) is no longer in service.Please re-send your email to us through the Contact Us page listedbelow. http://pages.ebay.com/help/contact_us/_base/index.htmlUsing this service will help us direct your email to the rightdepartment and quickly respond to your inquiry. Choosing the mostappropriate topic from this page will help us answer your questionfaster. REPORTING SPOOFIf you received this message after attempting to report an email thatappears to have come from eBay but actually directs you to another site,you must forward the message to us again by using the forward functionof your email program. Make certain that spoof@ebay.com is in the "to"field. Do not alter the subject line, add text to your message orforward the email as an attachment. We appreciate your assistance in this matter and apologize for anyinconvenience this may have caused you.Sincerely, eBay SafeHarbor TeamTips to Avoid Spoof:To help our members better protect themselves from spoof Web sites, wehave developed a new feature for the eBay Toolbar called "AccountGuard." Account Guard includes an indicator of when you are on an eBayor PayPal Website, buttons to report fake eBay Websites, and a passwordnotification feature that warns you when you may be entering your eBaypassword into an unverified site. To learn more about the eBay Toolbarwith Account Guard, open a new browser and typewww.ebay.com/ebay_toolbar into the address bar. Note that eBay willnever send you an email that includes a download as an attachment or alink that goes to a page with a download.eBay also recommends that you ensure that your Web browser, operatingsystem, and virus protection software are up to date. Check for updatesat the "Windows Update" link on www.microsoft.com and scan your computerfor viruses often.

Which is all very well and good but I’M NOT AN EBAY MEMBER.

So I follow the link provided to “report spoof” only to be confonted by a series of questions which I dutifully answer and eventually end up on a page telling me how, as an eBay member, I can:

  • Know that an email is really from eBay
  • Tell if Email and websites are impersonating eBay; or
  • An overview of what to do if I suspect account theft

Which would be realy helpful except I wouldn’t have bothered to come here if I didn’t already suspect some kind of fraud because, well geee, I’M NOT AN EBAY MEMBER.

Scouring the page a littlke I found, among all these options, an “Email Us” link which of course I cheerfully click on only to be confronted by a screen asking me to Sign-In which as you know by now is not possible because: I’M NOT AN EBAY MEMBER!

However, being the kind souls that they are, there is also another button marked “Register, it’s fast and free.”

So it would seem that to contact eBay in order to inform them that their system is being used to send unsolicted email to someone who IS NOT AN EBAY MEMBER requires me to become an eBay member. Hmmmm.

Thankfully, it’s even easier and “free’r” to configure my email software to block anything coming from eBay.

CSS: Debugging Position and Size of Elements

By

I’ve been getting into a lot of CSS stuff over the last couple of days and I’m really digging it; it’s so much easier to lay stuff out than with tables! (OK I’m a little slow but I’ve never been much of an HTML man myself.)

One of the most helpful things I’ve learned (thanks to my mate Stuart) is that when trying to layout, position and size an element, it helps to set the background colour to something really obvious and in contrast to the rest of the page (in my case I used bright orange). This way you can see exactly where the borders and margins are.

Thanks Stu!

The Joy of Mighty Mouse

By

My tolerance for things (anything) that don’t work the way I expect them to is about as low as you could possibly imagine. Just ask my work colleagues about how painful it is to work with me when I have to use Eclipse. (And before the flame wars start, it’s not a bad product it just doesn’t work the same way I do. In fact after my last blog entry, Jon described Eclipse as well and truly “Opinionated Software”. I couldn’t agree more.)

So anyway, it came to pass that on Friday 23rd of December, 2005 my laptop died. Yes, my beloved PowerBook just wouldn’t start up. (Of course those same colleagues that deride me for my whining about Eclipse also took great pride in cajoling me over my woosey “laptop”.) Unfortunately it had apparently suffered one too many falls – about half-a-dozen to be precise – as I made my way around the globe earlier in the year.

Distressed as I was I naturally raced off to the Mac store to hand over the carcass and purchase a new, emergency, computer. Knowing full well that the MacIntel laptops were just around the corner – and being prepared to wait for one– I decided to buy an iMac instead. (Yes, yes. It was a G5 which as of three, count ’em, three days ago has become obsolete.)

As I was wandering around the store waiting for my machine to have 2GB RAM installed, my brother – oh yes, he was with me for moral support :) – started playing with a Mighty Mouse; just like the one included with my new iMac and the same ones that nobody (including me) liked. (I had twice attempted to use one and twice failed. James even offered me his for nix as he disliked it so much!) “Hey! This is pretty cool!” my brother yells across the shop floor. “You have to be kidding me!? Those things suck ass! I just can’t seem to get the right-click thing to work!” I replied.

It was true. I had just never been able to get the right-click to work. It was a shame really because I really like the tactile sense of the track-ball thingy; it’s almost erotic..ok, forget I said that. Anyway, after explaining my issues and demonstrating my complete inability to operate the Mighty Mouse my brother emphatically exclaims “You’re a retard! How can you find it so difficult to use? The only explanation is you’re a retard!” Nice. So after some investigation in the shop and after providing much entertainment to the staff as a matter of consequence, he (my brother) deduces the problem: “You’re resting your hand on it and gripping” hey says. “Of course I am. How else does one use a mouse?” I enquired. “My arm and hand will get tired if I don’t!” I refused to believe that this mouse was any good at all. What a piece of crap. I wouldn’t be budged until he said something that really hit a chord: “Think about how pianists hold their hands. They don’t rest there entire hand on the keys, just their finger tips and they don’t get tired arms.” And what do you know? It worked.

The moment I stopped gripping the mouse and instead lightly holding it with my fingertips, the moment I was able to right-click just fine. What’s even more impressive is that at the end of a day in front of the computer, my hand no longer feels fatigued from using the mouse all day. Who would have thought? I wonder if the mouse was design in this way purposefully or whether it was sheer luck? Whatever the reason, I now love my Mighty Mouse and what’s more, I actually miss it!

Databases: A Necessary Evil?

By

It’s an attitude that I see all too often in developers, especially those that label themselves Object-Oriented Purists who are supposedly capable of precise, rational thought, above and beyond that which we might expect from your mere mortal developer.

Ever since my little rant on the subject over a year ago now I have been tempted time and time again to write something more but each time I go to put finger to keyboard I’m overwhelmed with a sense of resignation to the fact that when it comes to relational databases, most people just don’t get it. If I only had a dollar for every time a developer has adamantly told me that foreign keys are a waste of time and that somehow primary keys are a neccessary evil to satisfy the requirements imposed by the database so that we can look up a record. “Why would I need all that nonsense?” they chortle rhetorically, “my application handles all that stuff just fine.” Sure it does, so prove it!

What I find even more frustrating is the FUD spread by those I expect to know better. Case in point. I was doing some reading of old Ruby On Rails – yes, my shiny, not so new, toy – newsgroup postings when I came upon this from none other than Mr. Rails himself:

And let it be no secret that I consider the database a necessary evil for the object-oriented domain model. Not the other way around. Hence, when given the choice between implementations that pit OO model against database purity, I will almost always side with the OO model. – David Heinemeier Hansson

Now the statement just quoted was apparently a justification for Single Table Ineritence and the absence of Mutliple Table Inheritence in rails. Fine. I have no issue with this at all. In fact one of the things I like about Rails is the fact that it is unashamedly “Opinionated Software”: stuff works the way it does in Rails because, well, because that’s the way someone decided it should. So why shy away from this with some spurious argument about what is/isn’t good database design? Why not just admit that it’s a personal preference and indeed that’s the real reason it’s like that? Would you consider Active Record a necessary evil or simply a design choice? I guess it depends who made the choice ;-)

So anyway, let’s clear a few things up. Firstly, I’m fairly sure that when he (DHH) says database what he actually means to say is relational database – surely he doesn’t mean Object-Oriented Database? Secondly, even though he means to say relational database, what he actually should be saying is SQL database – believe it or not there’s a BIG difference!

Admittedly C. J. Date is not the most exciting read for many people but if you take the time to read some of his work on Relational Database theory, you might be compelled to re-consider your notion of the so-called “impedence mismatch” between Object-Oriented Design and Relational Databases:

… As far as I’m concerned, an object/relational system done right would simply be a relational system done right, nothing more and nothing less. – C. J. Date

I found it fascinating when I spent some time at a university many years ago that database theory was the least popular subject. Maybe it’s just me? Maybe I really enjoy the subject because I see elegance and simplicity and yet enormous power in Relational Databases and it Just Made Sense™.

Relatonal Databases surely aren’t as sexy as Ruby or Rails but neither are they glorified record management systems. They are very precise and provably correct repositories for our data. So, do what you will with databases, treat them as evil if you wish. but I think it behooves us to try and understand what we actually think we’ve supposedly moved beyond.

Update 18 January 2006

Primary Keyvil, Part I

Subversion Gotcha #17

By

Ok, so actually it’s the first that has bitten me but calling it #1 implies it’s the worst one there is and who am I to bestow that honour ;-)

I refer you to this positing in an SVN news group.

It seems that by default, when using Berkely DB with SVN, the default setting is to auto remove log files. Now log files serve a purpose: they allow you to re-play transactions. If those log files no longer exists…no guesses needed.

The rationale for the decision to have this behaviour by default (and I’m paraphrasing): We (the SVN community) don’t want people to complain to us with silly stuff like my disk is full. Rather we’d prefer that in the unlikely event of a repository crash, we’d rather that poor sod looses his days work. We made a trade-off between convenience and security.

Hmmm…let me think about that. How often does my hard disk crash? Almost never. And how often do I need to restore from a previous version of a file? Almost never. And how often do I back up my hard disc? Every day. Gee…maybe I don’t need a versioning repository?

If I said that at work, I’d be laughed off the premisis. Why? Because a repository is more than just a network filesystem. Moreover, it holds one of my companies major assets: the source-code.

I think I can live with my disk filling temporarily every once in a while versus losing a days work multiplied by 50 developers. In the worst case no one can check in. At least we know there’s a problem.

So anyway, this bit me last night when the server on which my SVN repository resides had an NFS failure and corrupted some files. No problem, we can just replay the log…oh they’re not there!

One could argue that I (as the maintainer of the repository) should have known about this option and turned it off. However that argument simply doesn’t wash as the main argument for turning it on by default in the first place was that most people coming over to SVN won’t know enough about how to configure SVN to do the right thing so a choice was made in favour of convenience.

Thankfully, we have daily backups and (in this instance) we only lost two commit sets. So what am I whining about? I’m whining in the hope that this doesn’t happen to you under more critical circumstances.

So how about turning that option off by default and putting a big notice in big bold red lettering on the front cover saying “If your disk fills up, it’s most likely the logs. Go delete the log files for any days for which you have backups. Leave the ones for which you presently have no backups – ie todays.” Not so hard now is it?

How To Write eql?() in Ruby

By

So, as I’ve been delving into Ruby more and more of late and I needed to write an eql?() method for one of my classes. (eql?() is the Ruby equivalent of equals() in Java.)

Understanding how to write an equals() method in Java is one of the most fundamental yet poorly understood practices (if you’re not worried about equals() or hashCode() then I suggest you never use a HashMap) and I wondered if the same was true of Ruby.

The most common mistake looks like this:

public boolean equals(Object object) {
  if (this == object) {
    return true;
  } else if (**!(object instanceof MyClass)**) {
    return false;
  }

  MyClass other = (MyClass) object;
  return this.x == other.x && this.y == other.y;
}

Spot the mistake? It’s subtle yet very VERY wrong. Thankfully – now that we’ve largely managed to get over our obsession with deep inheritence hierarchies – it’s effects aren’t felt that often. The problem is that equals() needs to be symmetric: a.equals(b) should return the same result as b.equals(a).

Now, imagine a class Person with attributes of name and address and another class Employee extends Person with an extra attribute of company. Given the previous implementation of equals, what do you think the chances that the following two statements will return the same result?

person.equals(employee);
employee.equals(person);

So anyway, unlikely or not, it’s still no excuse not to be precise so, in Java the canonical form of an equals() method should look roughly – give or take some formatting and style – like:

public boolean equals(Object object) {
  if (this == object) {
    return true;
  } else if (object == null || **getClass() != object.getClass()**) {
    return false;
  }

  MyClass other = (MyClass) object;
  return this.x == other.x && this.y == other.y;
}

Now we’re comparing based on the actual class and as such the implementation is symmetric; no more problems.

Assuming I still know next to nothing about Ruby, I decided I wouldn’t let my Java habits get in the way of learning something new so I searched the ’net for some examples of how to implement eql>().

After failing dismally to find anything non-trivial, I realised that Rails probably had something in ActiveRecord::Base and I was rewarded with:

def eql?(object)
  self == (object)
end
def ==(object)
  object.equal?(self) ||
  ( object.instance_of?(self.class) &&
    object.id == id &&
    !object.new_record? )
end

Nothing too outrageous: eql?() simply delegates to == (nice syntactic sugar); and == does pretty much the same thing as we would have done in Java only a little more terse. (object.instance_of?(self.class) is Ruby’s way of saying getClass() == object.getClass(); the Ruby equivalent of Java’s instanceof is kind_of?().) We could easily re-write this – although I wouldn’t in practice – as:

def ==(object)
  if object.equal?(self)
   return true
  elsif !object.instance_of?(self.class)
   return false
  end

  return object.id == id && !object.new_record?
end

So it seems – I trust the Rails guys to get this stuff right– that the same rules apply in Ruby as in Java. (I had no real reason to suspect otherwise but hey, it s nice to have it confirmed.)

Now if only someone could explain to me why Hash#reject() and Hash#select() aren’t symmetric: one returns a Hash; the other an Array.

Update 2009-11-02

Almost 4 years later I stumbled on this post and to my horror noticed that my naivety with Ruby at the time allowed me to believe the Rails code when really I shouldn’t have. Here’s the way the eql? method should have been written in the first place:

def eql?(object)
  if object.equal?(self)
   return true
  elsif !self.class.equal?(object.class)
   return false
  end

  return object.id == id && !object.new_record?
end

Or, if you don’t care about the optimisation:

def eql?(object)
  self.class.equal?(object.class) &&
    object.id == id &&
    !object.new_record?
end

Here Come The Minions

By

Well, just as Jon (and others) predicted: M$ developers are apparently beginning the move to Rails. That’s just Marvy!

I had taken comfort in the fact that .Net had disuaded a large proportion of developers from taking up Java and had hoped (nay prayed) that it would continue to keep them amused for some years to come but alas, the secret is out. Clearly the appeal of a language that gives every developer the ability to create a train wreck faster than ever before is too much resist.

I wonder how long it will take for M$ to get a patent on Ruby (and/or Rails for that matter). It seems like the only sensible thing to do ;-)

Patching Rails

By

Last night I was writing some database migration scripts and I wanted to add a not-null column to a table. The migration stuff is so cool that I was able to write something like this:

class AddExternalIdToListings < ActiveRecord::Migrationdef self.upadd_column :listings, :external_id, :string, :limit => 10, :null => trueadd_index :listings, [:external_id], :unique => trueListing.reset_column_informationListing.find(:all).each do |l|l.external_id = l.idl.save!endchange_column :listings, :external_id, :string, :limit => 10, :null => falseenddef self.downremove_column :listings, :external_idendend

This script first adds the new column allowing nulls (:null => true) then creates a unique index on it, updates each record to give the new column a value and finally modifies the column to make it not null (:null => false).

All well and good except for one thing: it didn’t seem to modify the column as expected. Looking at the source code for the PostgreSQL adapter, I could see that the code change_column() has (at least) two bugs. (Ok, strictly speaking one bug and one omission.) The first bug means that it never actually executes the intended statement. The second (the omission) means that even if the statement were executed, most of the specified options (in this case the :null => false) would have been completely ignored.

Enter the wonder of Ruby and extended/modifying classes on the fly.

Disclaimer: I’m no Ruby nor Rails expert. I’m sure there’s a “better” way to do this so if anyone wants to take this code and submit it as a proper patch, then please, please, please go for it. For my needs, this does the job nicely.

Rails allows you to add functionality via Plugins. In this case, I decided to make a “patches” plugin that will allow me to easily override or extend rails to get around any bugs (or omissions) that I encounter in my travels.

So I ended up with two files. The first vendor/plugins/patches/init.rb is executed by rails. In my case it contains only one line:

require 'postgresql_adapter_patches'

This simply loads the second file (vendor/plugins/patches/lib/postgresql_adapter_patches.rb) containing the actual code that performs all the black-magic (although it’s actually fairly straight-forward):

module ActiveRecordmodule ConnectionAdaptersclass PostgreSQLAdapterdef change_column(table_name, column_name, type, options = {})native_type = native_database_types[type]sql_commands = ["ALTER TABLE #{table_name} ALTER #{column_name} TYPE #{type_to_sql(type, options[:limit])}"]if options[:default]sql_commands &lt;&lt; "ALTER TABLE #{table_name} ALTER #{column_name} SET DEFAULT '#{options[:default]}'"endif options[:null] == falsesql_commands &lt;&lt; "ALTER TABLE #{table_name} ALTER #{column_name} SET NOT NULL"endsql_commands.each { |cmd| execute(cmd) }endendendend

In essence, all it really does is override the definition of the change_column() method in the ActiveRecord::ConnectionAdapters::PostgreSQLAdapter class. In my case, I just copied the code from add_column() and modified it to suit my needs. Of course this is a blatant violation of the DRY Principle but hey, shoot me :-).

All in all I’m impressed by how trivial the whole processs turned out to be and has made me think about writing some actual plugins; I’ll leave it to the experts to fix it for good ;-).

The Ruby Way(tm)

By

I can’t help but be amused at the number of times I see the term “The Ruby Way” (or similar) used as a euphemism for “Better than {Java,C#,Python,Perl,etc.}” It seems to be one of those terms (like “Un-Australian” and “Un-American”) that can be used to support or attack anything based largely on personal preference.

Case in point: The discussion and ensuing ruckus over Humane Interfaces. What seemed (to me at least) to be an interesting talk on the subject rapidly (as seems to happen all too frequently) into a “mine’s better than your’s” sledging match.

Unfortunately, Fowler did begin his discussion with “Hanging around the ruby crowd…” and followed that up with “…compare the list components in Java and Ruby” which amounts to pouring gasoline on a bbq. However, what almost everyone fails to see (or possibly I fail to see that they see) is that the concept has almost nothing to do with the underlying language and far more to do with the people (surprise surprise).

Java is full of Swiss-Army classes as is Ruby. Ruby seems to have some very intelligent and articulate pracitioners as does Java. In many ways, Ruby (like Perl) seems to almost encourage bad habits in those less versed in The Ways™. Java OTOH attempts to prevent these same problems and yet creates a whole slew of others.

Disclosure: I like Ruby, alot! but I don’t hate Java as a consequence. In fact I find that besides some really nice language features that I really like, I don’t find that I think that much differently in either. Then again, I’ve never liked Struts, I’ve put up with Hibernate and left the J2EE stack along time ago. Alas, ActiveRecord is not much better (yet). It lacks many things that I’ve come to appreciate in ORM tools but, in its defense, it’s still relatively early days and what is there is relatively clean (from the point of view of one using the library) but take a look at the code and tell me there aint a whole lotta spaghetti in there!

Most people (probably myself included) don’t get software development, don’t get OO, don’t get “it” in general. So let’s not get sucked into thinking that somehow the language is to blame. Sure it has an influence but honestly now, horses for courses: People think differently, taste differently and smell differently. Get over it!

Maybe look at yourself first and ask the question “Do I get what they intended?” If you think the answer is yes, then ask again. If the answer is still yes, then how about taking aim at the people involved in creating the frameworks next. The underlying language is a very soft target.

First come up with a definition for “good” and then prove to me there is a direct correlation with the language.

Dojo or Prototype or ...?

By

I’m about to start adding “funky” Look & Feel stuff to my Rails app and I was wondering what the general consensus (if there even is such a thing) is on JavaScript libraries.

I really don’t care so much about the ease or otherwise of making XMLHttpRequest calls; this is the least of my worries – it’s trivial to do manually. What I’m more interested in are things such as Drah & Drop, Accordians, Select-as-you-type, and other more general DHTML layout stuff.

Rails itself ships with prototype+scriptaculous which I’m lead to believe are quite good. My mate Andy on the other-hand has played a bit with Dojo and likes that too.

Anyone care to share their own experiences?

Don't Give Razor-Blades to Children

By

I’ve no idea who first coined this phrase but I heard it from Steve.

This was to be solely about Rails schema migration but it turned into a partial rant (surprise surprise) about playing with Ruby and Rails. Never fear, the migration bits are still here; they’re just at the end instead :)

Developing in Rails as a one- or two-man-band is very rewarding but I’d like to see how it scales to many developers and more importantly, to developers of radically different levels of experience. As you probably gathered from my previous post, my prognosis on this last point isn’t particularly flattering.

I like convention over configuration so long as the conventions don’t get in my way; and so far they haven’t. I think the idea of “flexibility” in software is highly overrated. The whole J2EE stack is a perfect example of bloat in an attempt at being all things to all people.

Don’t get me wrong, I love Java. I will always like it. It does pretty much everything I could want and do feel very productive with it – especially when compared with the pile of steaming turd that is Flash/Flex – but I have to admit that I do like The Ruby Way ™. I must have been a Smalltalk wanna-be in a previous life. It’s not for all things nor for all people but it might just be for me on the kinds of projects I enjoy doing.

So far I’ve found Ruby/Rails to be easy to test; that it facilitates adding new behaviour VERY quickly; and that the teeny bits of SQL I do need every now and then aren’t painful in the slightest. I love partials; caching; declarative relationships; validation; acts_as_xxx; components; etc.

I don’t like fact that there doesn’t seem to be a way for components to have relationships to domain objects – for example my address component needs a State which is an active record object. Tool support is pre-historic when compared with Java. I use TextMate on the Mac which is pretty darn good and there is RadRails of course but to be honest, right now – although the road-map looks very promising– it isn’t actually much better than TextMate except for debugging.

Anyway, the upshot of that little rant is to say that whilst I’m still splashing around in the kiddies pool, the water still feels good and is tempting me to want to try swimming in deeper water.

So anyway, back to the topic I originally had in my head.

If anyone has been playing with rails then at some point they’ll want to have a play with data/schema migration. I used it tonight and it worked as advertised.

In short, you create a number of files named 001_xxx, 002_xxx, etc. Rails then creates a table (schema_info) that contains the current database schema version. When you run a migrate, it (rails) will execute the scripts necessary to bring you from whatever version you are currently at (may be 0) to the latest version (by default) or a nominated version (using VERSION=#). You can even downgrade by specifying a previous version.

Besides migrations based on version numbers it essentially supports a DB independent schema description with the ability to escape to SQL if need be (like for those pesky little FK constraints that no one wants to talk about but should be locked-up for doing without). Honestly the “DB independence” thing isn’t the biggest concern for me in the world but it is nice. It would be even nicer if rails extended the concept to include foreign key constraints (the model has declarative relationships anyway!).

You can also use your rich domain model to play with the new schema in the migration script too! So, for example, you can add reference data or munge the existing records to suit the new schema. Again you can even execute raw SQL if need be!

If you’re interesting in how this really works, I can recommending reading thisand maybe thisand possibly thisand the RDOC can be found here.

The only issues I’ve had are that transaction management within the migration is a little dubious: I can’t seem to find a way to execute a batch of DML – as opposed to DDL– in a single transaction. Rather, it seems to commit each statement. The upshot of this is that it’s possible to end up with a database in a weird state where some of the statements executed but the schema version hasn’t been incremented. Thankfully you do get an error message so you know something screwed up and you can manually increment the version number and then have rails downgrade for you.

This only happened to me once and then only in development so it’s not a huge issue but one to be mindful of.

So, my new shiny toy is still shiny but I’m not about to give up my day job just yet. I still haven’t heard enough people bitching about it to make me feel comfortable that there is enough understanding of the technology in the main. I am however doing a real-life project using it and so far so good.

Ruby on Rails: 100,000 morons can't be wrong

By

So I have to admit that not only am I a cardpod-carrying member of the apple cult, but lately I’ve been dabbling in a bit of voodoRuby-on-Rails as well and so-far, me likey. I think it’s one of those tools that people will either get or not. If they do, it’ll be fantastic; if not…

Rather than give you my personal take on this, I thought I’d take a slightly different approach and get in touch with one of my inner-morons for a more balanced perspective.

Ahem…

I’d like to start by saying outright that I think RoR will be a good fit for most large corporate development shops. I can see it delivering 20x, 30x maybe even 50x improvements in efficiency however I do see some short-comings, probably due to it’s relative immaturity when compared with Java.

If you look at most of the projects that are using Rails and Ruby at the moment, the code-base consists of dozens, maybe hundreds or possibly even a few thousand lines-of-code at most; Certainly nothing that compares to the size of projects we are used to working on which are in the order of tens if not hundreds-of-thousands of lines-of-code. But fear not, we have a plan to ensure it’s readiness for enterprise use.

We have two choices: develop applications and components on an as-needs basis; or try to build some common infrastructure that all projects can use.

The first option sounds dangerous as it will no doubt lead to everyone doing it slightly differently which in turn leads to lots of unnecessary duplication of effort. So as part of the next project, we plan to produce a framework (Ruts?) that will sit on top of RoR upon which all the teams can build. This way we will have better management and control over the infrastructure.

We’ll start by checking the source code for Ruby and Rails into our repository so we can patch them whenever we need to. This means we don’t have to wait for patches to become available in production versions. It also has the added benefit that when the API’s change our code won’t need to be re-factored as a consequence. Isn’t open-source great!

Next we’ll address configuration. There really needs to be a way to place all the configuration in XML files. XML is, after all, THE standard; we’ve been using XML successfully in Java for years and everyone understand it. We’ll start with database connection details, then move on to other areas. One area of particular interest will be database schema generation. At the moment Rails only supports coding the SQL directly. Unfortunately this doesn’t allow us to write database agnostic DDL; enter XML. If we create an XML-based language for defining the schema, we can then generate the SQL for each desired database; heck we can also generate the appropriate Rails model classes as well including relationships, etc.

We’ll also need clustering – every enterprise application needs clustering. To this end we’ll extend rails – we have the source – to support transparent clustering by sending session state to a master controller server that will then send it to all the nodes in the cluster. This will require serialisation and class version management which ruby already has built-in.

We see other improvements in efficiency in terms of testing. We find that due to the very slow turn-around time of Java web applications, our developers spend a great deal of their time writing tests. Rails on-the-other-hand has such a quick development cycle time that we can dispense with much of the automated testing in favour of manual testing.

Having said that, we have noticed that each time the database schema or configuration changes we have to stop and start the server so we will also include an extension to Rails that looks for changes in the configuration and automatically refreshes rails. Again, once implemented in the framework, each project will benefit.

Another limitation in Rails is the MVC implementation. Again, it’s pretty good but it could still be improved. We’ve known through years of experience now that trying to put all that code into one controller class just doesn’t work. Instead we will create command objects, wired together using XML and a generic AbstractController that will read the configuration file and work out what to do. This will be much simpler and we envisage huge time savings as a result.

Also the active-record stuff might be a good starting-point but it will need to be enhanced a bit for real enterpise applications. For a start, what it needs are DAO’s, one for each table in the database. Again a few classes in this respect would do wonders for productivity. We might even write some code that could generate DAO’s from the schema XML configuration discussed earlier.

Come to think of it, if we had some kind of container, then it could manage all this for us and more including transaction management, dependency injection based off an XML file, etc.

We’ve also been looking at the query language. It’s pretty good but it’s not very rich and it’s basically just SQL injected into your source. What Rails really needs is some kind of Object Query Language along the lines of hibernate. In fact, because hibernate is open-source, we might want to consider replacing active-record with a hibernate re-write (Rhibernate?)

So, as you can see, with a few little tweaks here and there, Ruby-on-Rails might just be what we need to get our enterprise development teams moving towards Web 2.0. We just need to work out how to get Rational Rose and ClearQuest integrated to generate all the code for us and we’re set to go.

Thank-God for Wireless

By

When I arrived home I realised I didn’t have my keys with me and my brother had (selfishly I might add) gone out somewhere. But, thanks to the wonders of modern technology here I am, sitting on the steps of my apartment building, chatting on IM, checking my email, reading RSS feeds and of course, authoring a blog entry.

What else would a geek do under the circumstances I ask?! ;-)

Mocking my Visitors

By

I mentioned in a comment earlier this week that I like Builders as they allow me to separate out the ickyness involved with construction from my nice pristine objects. Besides anything else, it allows me to layer on functionality: first implement the domain objects, assembled by hand for testing purposes; then create another layer – the builder – that will automate the construction process.

Of course being the good little TDD weenie that I aspire to be, at some point I want to test that the builders are generating the correct structure.

IMHO, the utterly evil-broken-and-wrong approach is to expose all the properties on all the nodes in the graph – I use the terms node and graph generically here to refer to objects related in some fashion – for reasons I’ve harped on about more than enough.

Another approach – that maintains encapsulation – is to implement equals() for all the nodes in the graph. The idea for testing then is to create the expected structure by hand (just as I had already been doing) then use the builder to create another and assert that the two are identical. I have actually used this approach before and while it worked just fine, it never really felt Good™. I’m not sure why; just an intuitive ookyness.

More recently though I tried a different approach: using a visitor. Again the approach was similar: constructed the expected structure by hand; then use the builder to make another; and finally assert that the two are identical. This time however, the idea was to traverse the expected structure and match, node-for-node, with the actual. The neat thing about this approach though was that because my visitor class was an interface, it was trivial to use EasyMock to do all the grunt-work for me. (EasyMock also allows mocking classes however I still prefer interfaces.)

The idea is to create a mock visitor using EasyMock and pass that to the accept() method of the structure I had created by hand to set-up the expectation. Once that was done, I could then simply pass the same mock to the accept() method of the structure constructed by the builder:

public void testBuilderMakesIdenticalStructureToOneBuiltByHand() {
    // Create the two structures
    Node createdByHand = createByHand();
    Node createdByBuilder = createByBuilder();

    // Visit the one created by hand to set-up the expectations
    NodeVisitor visitor = EasyMock.createStrictMock(NodeVisitor.class);
    createdByHand.accept(visitor);
    EasyMock.replay(visitor);

    // Visit the one created by the builder to verify
    createdByBuilder.accept(visitor);
    EasyMock.verify(visitor);
}

private Node createByHand() {...}

private Node createByBuilder {...}

Note: I’m using the latest version of EasyMock that supporst JDK 1.5 generics however I’m not (nor will I ever be) using static imports as suggested in the documentation!

This time, it felt Good™. I could use the same visitor for testing, reporting and persistence, all without the need to break encapsulation.

Now while I’m really not keen on igniting a religious flame-war over mock objects in general nor mock object libraries in particular, the fact that EasyMock works against the real interfaces – as opposed to using string descriptions ala JMock– was a huge advantage in this case.

Sufferin' Sukertash

By

Wouldn’t you know it! A week after The Book leaves the warehouse, I find a mistake in the very first figure! I’ll never criticise another book EVER again. Ok, I’ll criticise the book but not the author(s).

Thankfully there’s an errata page; not that I’ve ever visited one for a book that I’ve bought mind you but still, it’s somewhat comforting to know.

What’s particularly amusing is that the first error submitted was by me, a co-author LOL.

Constraining Design in Search of Elegance

By

Rather than play with the latest shiny new framework, language, etc. my vice is continually trying new and/or whacky – for me at least– programming/design techniques. To be fair, I don’t tend to thrust these upon unsuspecting clients as the new way of doing things. Rather, I’ll start a new pet project of some kind and try to push the paradigm as far as possible and see where it – or I – break down.

Most of the time these “techniques” manifest themselves as a set of constraints or rules for coding; something akin to a manual Checkstyle or PMD for design rather than coding conventions. So just like constraining method lengths and Cyclomatic complexity help shape a design by forcing me to actually think about what I’m trying to achieve, I like to play with other types of constraints.

For example, James and I had a go at 100% TDD for a Swing application many, many moons ago. Again not so much because we think 100% TDD is necessarily a good (or bad) thing but more in attempt to push the idea as far as possible, just to see how it and we would react under pressure so to speak. The results were actually very interesting and made me want to find someone prepared to pay me money to build a rich-client application (Not using Eclipse RCP!)

After I started doing some Objective-C some months back, I was forced to deal with the fact that there was no such thing as a private method – everything in Objective-C is effectively public. I then started to think about what it might be like to apply the same thing to my Java code; what if I was forced to make every method public? How would that affect my design.

Interestingly it had a largely positive effect: I started making smaller classes with well defined behaviour that made sense to be public. In a way, I was forced to make myclass behaviour more cohesive. The problem was of course that, as with anything that is approached in such a strict and unforgiving manner, there are times when it just makes more sense to have a private method that can be re-used or more often, helps to make the code more readable.

So for the most part, I was happy with the outcome: assuming behaviour is public yet not wishing to expose all of that behaviour forces me to compose large classes from smaller ones thereby hiding “private” implementation detail in public methods on other, re-usable, classes.

More recently I decided to try a couple of other things out on a project. These were:

  • No if’s;
  • No casting to expose “conditional” behaviour; and
  • No getters & setters – i.e. tell don’t ask.

Nothing special here really, but I wanted to see how far I could push the ideas and what effect that had on my design and productivity.

The first – no if’s– is relatively simple to address through the use of polymorphism and Maps as jump-vector tables; techniques most people probably use anyway.

The second – No casting to expose “conditional” behaviour – is a little harder. To completely eradicate. Firstly, I was using Java 5 with “generics” to remove the need to cast items in collections – although if you’re not careful, the code can get quite messy with all the “devils horns” – however, the real problem comes when you have a group of classes all related via an interface where some of the implementations provide certain behaviour and others don’t. This was most noticeable when implementing anything that resembled a Composite Pattern.

Enter the Courtesy Implementation. In every case where I ended up needing to implement a method that didn’t “make sense” it would have been a programmatic error to have called the method on an instance of that particular class anyway so I simply threw an UnsupportedOperationException. At this point I wished that would happen by default; that by implementing an interface you could somehow say you weren’t going to support certain methods. A pretty stupid thing to want really, given I’m working in a strictly-typed language.

And finally, tell don’t ask. The code – comprising 50 main classes and slightly fewer test classes (tsk tsk) – has zero (0) getters and setters. Admittedly I wasn’t implementing a CRUD application so that made things easier but there were times when I thought I would need a getter but managed to get around that need quite elegantly (IMHO) through diligent use of simple call-backs (no real closures in Java unfortunately); more complex Visitors; implementing Comparable; etc. In other words, lots of interfaces.

One thing that did arise though was the constant fight against cyclic-dependencies. One example where this is particularly obvious is with visitor. The “standard” way to write a visitor is something along the lines of:

public interface Visitor {public void visitX(X x);public void visitY(Y y);}public class X {public void accept(Visitor visitor) {...}}public class Y {public void accept(Visitor visitor) {...}}

The problem with this is that the Visitor depends on X and Y yet the classes X and Y both depend on Visitor: cyclic dependence.

Interestingly, the “usual” way to implement the visitor would probably look something like this:

public class PrintingVisitor implements Visitor {public void visitX(X x) {out.println("X:" + x.getName());}public void visitY(Y y) {out.println("Y: " + y.getTotal());}}

But recall that I had imposed the constraint of no getters so instead re-worked it like this:

public interface Visitor {public void visitX(String name);public void visitY(int total);}public class PrintingVisitor implements Visitor {public void visitX(String name) {out.println("X:" + name);}public void visitY(int total) {out.println("Y: " + total);}}

Like anything, this is open to abuse, but there are no longer any cyclic dependencies and the only time the guts of X and Y are exposed is when calling on the visitor.

The example just shown is very simple and won’t work in all cases of course but it does highlight how a bit of extra thinking can lead to interesting, and hopefully richer and more useful, designs; the constraints I had imposed seemed to force me to think more about the behaviour and less about the data. For some of you freaks who find that very easy to do I’m very happy, but for mere mortals such as myself, having a few rules-of-thumb to know when I’m being “dumb” makes life that much easier.

Another really interesting thing for me in all of this is that statically-typed languages such as Java force me to make all my interfaces explicit. That is, I need to create physical interfaces so as to remove the cyclic-dependencies between concrete classes. However, with languages such as Ruby, Smalltalk etc, the interfaces are implicit. In a sense, Ruby and Smalltalk allow me to define interfaces at the method level; a much smaller level of granularity than is practical with Java. When I asked a old smalltalker friend of mine about how he would have dealt with cyclic-dependencies, he replied “we never worried about it; if the object responded to a message that’s all that mattered.” I repeated this answer to another non-smalltalk friend of mine to which he mused “and they probably created a lot of spaghetti!”

So, while many people are clamouring for more-and-more functionality from their programming language, API’s etc. I think sometimes I’d actually prefer less; so long as long as it’s the right set of course ;-)