Michael Kovacs' photos More of Michael Kovacs' photos
Recommend Me Cable Car Software logo

Thursday, March 23, 2006

Rails realities part 10 (rails plugins and riff)

A quick timeout from TSSS conference for a quick rails posting....

As of the rails 14.x series and the 1.0 release rails has introduced the notion of plugins to allow functionality to be added to rails applications more easily. I recently had need for some code that would give me a diff of model objects against the saved version or another instance of that type. So for example I have:

crazy_dog = Dog.find_by_name('CJ')
crazy_dog.temperment = 'excitable'
good_dog = Dog.find_by_name('Cody')
good_dog.temperment = 'calm'

I'd like some way of being able to easily diff these two objects' properties. I wasn't looking forward to writing something to take care of this and I figured that this is common enough of a problem that someone has to have already complained or written something to do this for me. Luckily technoweenie, a prolific contributor to the RoR framework, pointed me to "riff". Riff is a rails plugin that performs exactly what I need, a diff of model objects' properties.

Installing the riff plugin into my app was as simple as going to the root of my rails app (foo) and typing:

michael-kovacs-computer:~/foo mkovacs$ svn export http://tfletcher.com/svn/rails-plugins/riff/ vendor/plugins/riff
A vendor/plugins/riff
A vendor/plugins/riff/test
A vendor/plugins/riff/test/test_setup.rb
A vendor/plugins/riff/test/riff_test.rb
A vendor/plugins/riff/init.rb
A vendor/plugins/riff/lib
A vendor/plugins/riff/lib/riff.rb
A vendor/plugins/riff/README
Exported revision 8.

Here's the part of the post where I rant about how the rails core team is adding needless complexity by modifying the syntax of the ruby language.
Unless you're running edgerails this plugin will not work out of the box. If you try calling "diff" on your model objects you'll get an exception at the following line (line 30 of riff.rb):

diffable_attributes = content_columns.map(&:name)

The problem is with the &:name portion. That isn't standard ruby syntax. The rails core team apparently thinks that the following code is too verbose:

diffable_attributes = content_columns.map { |c| c.name }

The difference between the two is that the Proc object that is passed to the map method is created by rails implicitly while the "old fashioned" way is to create it yourself. To non-ruby folks the "&" is a reference to a Proc object which is just a snippet of code to be executed. The ":name" is a symbol. In this instance "&:name" in English means "Create a Proc object and call 'name' on each object contained within the content_columns array." So the second snippet of code is how you would write it with standard ruby syntax. Nice, huh? I can see how saving those extra keystrokes and adding another level of abstraction adds so much value and is totally worth the extra complexity. *sigh*

Anyhow, replacing the line above in riff.rb and continuing my code example above I can now perform diffs on my model objects by simply restarting my server and adding the following code:

crazy_dog = Dog.find_by_name('CJ')
crazy_dog.temperment = 'excitable'
good_dog = Dog.find_by_name('Cody')
good_dog.temperment = 'calm'

good_dog.diff(crazy_dog) -> { :name => ['Cody', 'CJ'], :temperment => ['calm', 'excitable'] }

And that's it. In 5 minutes I have the ability to diff my model objects. Great stuff. This works fantastic for all property level diffs that are built in types. For complex types, like related objects this won't work but this is a good building block.

Note to core rails dev team members. Don't get crazy adding syntactic sugar to rails that adds needless complexity without much gain. It's already difficult enough to learn a new language and framework without the added fun of trying to figure out all these extensions to the language that aren't documented anywhere. I only knew WTF was going on here because I talked to technoweenie and he told me what this was.

2006 Java ServerSide Symposium - Day 1 (arrival and opening keynote)

I'm hangin out at TSSS here in Las Vegas the rest of this week. This is a very developer centric conference that feels more like a subset of what JavaOne used to be before it turned into JavaYawn. I arrived last night, grabbed some dinner, lost some money and went to bed "early" (for Las Vegas) at midnight.

Fully rested and ready to go after some morning yoga stretches I actually made it early enough to partake in the pre-conference refreshments (Only coffee was served, leaving us tea drinkers to fend for ourselves. TechTarget is really taking this Java only thing very seriously.). The opening keynote was Geir Magnusson who invited Cedric (former BEA-er), Hani, Cameron, and Patrick (Current BEA-er)to join him on stage for what was sort of a keynote BOF with heavy audience interaction. Early in the talk Geir asked a show of hands who doesn't use J2EE. There were a few hands and Geir walked into the audience to ask one of those why they're not using J2EE and what they are using. The nameless gentleman, obviously confused about what J2EE is, responded to the question by saying that they were using servlets as well as EJB.

When asked for predictions for 2006 the answers were mostly predictable with the mention of AJAX and POJOs but the biggest surprise was Patrick's assertion that BEA is going to have an application framework that allows authoring if applications via a giant XML file. :-) So I guess we should all look for that this year sometime ;-)

Towards the end there was a question posed to the audience about ruby on rails. How many folks have heard of it? Several hands were raised.... How many folks have taken a look at it? Less hands... How many folks have used it for a production site? I think I saw maybe 2 other hands besides myself. How many folks looked seriously at rails and decided not to use it for their project... There were a few hands here as well but nobody would come forward with the reasons why they made their choice, so I decided to come forward with some of the reasons I would not to use the framework that were based on some of the problems that I've highlighted in this blog. I did say that despite some of these shortcomings that the framework generally accomplishes what it sets out to do.

This page is powered by Blogger. Isn't yours?