Kerry Buckley

What’s the simplest thing that could possibly go wrong?

BVB: Big Visible Belly graph
8 November 2008

Rails 2.2 Envycast Review

I've been a fan of the RailsEnvy guys (Gregg Pollack and Jason Seifer) ever since their "Hi, I'm Ruby on Rails" spoof of the "I'm a Mac" ads, and have been listening to their podcast ever since. I even got a mention on it once. Well that's not strictly true – I wasn't actually mentioned, but a patch I'd contributed to Capistrano was, which is close enough.

Recently, Gregg and Jason have branched out into screencasts, but I hadn't actually watched one because (understandably) they charge for them, and I was too tight to cough up the cash. £1200 for a new MacBook, no problem. A fiver for a screencast? What am I, made of money?

Anyhow, when I saw that they were looking for people to review their Ruby on Rails Envycast, covering the latest goodness in Rails 2.2, I jumped at the chance to get a free copy. A wonderful example of cognitive bias, given that I wouldn't have agreed to write a review just to be paid $16.

What do I get for the money?

The basic $9 gets you the screencast and a set of code samples to go with it, or for $16 they'll throw in Carlos Brando's Ruby on Rails 2.2 PDF too. Alternatively the PDF is available on its own, also for $9.

Video

The video is available in Quicktime or Ogg formats at a resolution of 569×480, as well as a version optimised for iPhones and iPods. Total running time is just under 45 minutes, and incredibly the first 39½ of those go by before Jason makes any claims about Rails's scalability.

I don't know whether it's unique, but the Envycast style of having the presenters chroma-keyed onto the Keynote presentation generally works very well. The visuals themselves are professional, although sometimes the 'sparkle' effect is a bit overused for my taste. The presentation style is much as you'd expect if you've listened to the podcasts, with plenty of cheesy humour to keep things interesting. I think having two people present in a conversational style is a big help.

The screencast is split into sections, each covering the new features for a different component (ActiveRecord, ActiveSupport, ActionPack, ActionController, Railties, internationalization and performance). The Quicktime version (not sure about the others) has bookmarks, making it easy to jump to a particular section. The whole thing is set against a variety of city skylines to liven the background up a little – by the way guys, that's Tower Bridge, not London Bridge.

Each new feature is introduced with an example, generally contrasting the 'old' way of doing something with the equivalent in 2.2. There's enough detail to get the idea of what's changed, without dwelling too long on each one. One tiny gripe with the code snippets on screen: the pedant in me hates seeing curly quotes in code, because I know if I typed puts ‘foo’ into irb instead of puts 'foo', it wouldn't work.

Code samples

The screencast comes with a set of code samples to illustrate all the features discussed in the screencast. These take the form of sample classes with Test::Unit test cases, along with rakefiles to run them. The sample directory contains a frozen installation of Rails 2.2, so all you need to do to run them is add the appropriate values to database.yml. I had trouble running them initially because they were inside a directory with a space in its name, but other than that it all worked nicely.

PDF

The PDF that comes with the $16 bundle is by Carlos Brando, well-known for his free Rails 2.1 book. It's available in the original Portugese, or translated to English by Carl Youngblood. The book weighs in at 118 pages, and as you would expect goes into more detail than the screencast. It claims to cover all the major changes in Rails 2.2 (I haven't checked!), and contains clear descriptions with examples.

Conclusion

So is it worth it? On balance, I think the answer is yes, although I wonder whether they'd sell more at $5 rather than $9 – after all, I can buy (to pick an example at random) the entire Naked Gun trilogy on DVD for roughly the same amount, and Gregg and Jason aren't that funny. The value is in collecting all the information in one place – you could trawl through the release notes and lighthouse tickets to get all the same information, but if you value your time at all, the screencast and PDF pay for themselves many times over.

Should you buy the PDF, the video or both? If you just want the hard facts, go for the PDF, but if you want to be entertained too (assuming you find the Rails Envy podcasts entertaining), get the video as well. The next episode, Scaling Ruby, is out now, and I might buy it just to see if Jason finally admits that Rails might actually be able to scale.

Technorati Tags:

12 June 2008

Defending Ruby and Rails in the Enterprise

I consider myself fortunate that the previous two projects I worked on (the BT Web21C Portal and Mojo) were Rails-based (actually it wan't just luck in the former case, as I had a part in selecting the framework). I love the expressiveness and flexibility of the Ruby language, the power and relative simplicity of the Rails framework, and the all-round awesomeness of tools like RSpec and Capistrano, and I don't particularly relish the thought of going back to Java (although I'm told that Spring is much nicer than last time I used it).

At our recent release planning session, I was assigned to a new project, which involves (among other things) exposing a CLI-based configuration interface as a web service. In our initial discussions, the four of us more-or-less agreed on a few initial decisions:

  • The exposure should be REST. Fortunately the people developing the upstream system shared this opinion.
  • Rails is an ideal framework for RESTful web services.
  • Ruby seemed like a good fit for parsing the command responses too.
  • Asynchronous behaviour would be handled using queues (probably ActiveMQ).

Since we'd all been working on Rails projects when the new team was formed, we assumed that this wouldn't be a particularly contentious route to go down, but unfortunately our director/architect/boss didn't see things quite the same way. He had two main objections:

  • Rails may make sense for GUI applications, but why on earth would you use it for a service? All our other [SOAP] services are written in Java.
  • At some point the application will need to go into support, and we don't have support/operations people with Ruby or Rails experience

I think the first point's easier to address, as I'd argue it's based on a misunderstanding: Rails isn't really anything to do with GUIs, but is a framework for creating MVC web applications. Virtually all the heavy lifting Rails takes care of is in the controller and model areas, with the creation of the actual visible GUI being left to the developer to take care of with the usual mix of HTML, CSS and Javascript. The only thing Rails adds is the ability to insert dynamic content using ERB – similar to the role of JSP in Java EE.

A RESTful web service is, to all intents and purposes, the same as a normal web application, but (potentially) without the HTML. All the power that Rails brings to web application development is also harnessed when creating RESTful services.

The second point represents a much more fundamental strategy choice. If the company makes the decision that all development is going to use Java (the language as well as the platform), then we inevitably lose the flexibility to choose what may appear (in a local context) to be the right tool for the job. Personally I think that would be a shortsighted and ill-informed decision: if that were the strategy, we'd presumably all still be developing in C, or COBOL, or Assembler. Or we'd have gone bust. But then I'm not an architect (incidentally, according to Peter Gillard-Moss, that's reason number 10 why I don't deserve to be fired), so what do I know?

However, if Ruby is considered an acceptable technology choice for "normal" web applications, we'll still need people with appropriate skills to support those, so the problem doesn't go away. I suspect even for a Java specialist, supporting a well-written Rails application with good test coverage is probably easier than supporting some of the spaghetti-coded Java I've seen.

Anyway, our arguments obviously weren't totally unconvincing, because we were given a couple of weeks to show what we could produce before getting a final decision. That time runs out on Monday, so if I'm unnaturally grumpy after that it'll be because we've been told to chuck all our work so far away and start from scratch in Java. Or possibly FORTRAN.

Update, 16 June Well we made our case, and we get to stick with Rails. Celebration all round!

18 December 2007

“You have to declare the controller name in controller specs”

For ages I've been getting an intermittent problem with RSpec, where occasionally I'd see the following error on a model spec:

You have to declare the controller name in controller specs. For example:
describe "The ExampleController" do
controller_name "example" #invokes the ExampleController
end

The problem seemed to depend on which order the specs were run in, and for rake it could be avoided by removing --loadby mtime --reverse from spec.opts. It was a real pain with autotest though, and today (my original plan of "wait for RSpec 1.1 and hope it goes away" having failed) I finally got round to looking into it properly.

It seemed that the error was being triggered by the rather unpleasant code I wrote a while ago to simplify testing of model validation. Digging into the RSpec source to see what was happening, I found that that error message only gets returned when (as you'd expect) you don't declare the controller name in a controller spec (specifically in an instance of Spec::Rails::Example::ControllerExampleGroup). The code that decides what type of example group to create lives in Spec::DSL::BehaviourFactory, and according to its specs, there are two methods it uses to figure out what type of spec it's looking at:

RUBY:
  1. it "should return a ModelExampleGroup when given :type => :model" do
  2. ...
  3. it "should return a ModelExampleGroup when given :spec_path => '/blah/spec/models/'" do
  4. ...
  5. it "should return a ModelExampleGroup when given :spec_path => '\\blah\\spec\\models\\' (windows format)" do
  6. ...
  7. it "should favor the :type over the :spec_path" do
  8. ...

I began to suspect that the problem was caused by the fact that my specify_attributes method wasn't declared in a file in spec/models, so I thought I'd try specifying the type explicitly. So instead of this:

RUBY:
  1. describe "#{label} with all attributes set" do

I changed it to this:

RUBY:
  1. describe "#{label} with all attributes set", :type => 'model' do

Sure enough, it worked! Not sure whether anyone else is likely to see the same problem (unless they're foolish enough to use my validation spec code), but hopefully if you do, a Google search will bring up this post and it might point you in the right direction.

26 November 2007

Rails Envy’s take on the werewolf question

This clip [MP3, 57s] from a Rails Envy podcast made me laugh. It's referring to Charles Nutter's recent musings on whether werewolf is killing the conference hackfest.

Incidentally, how often do you get the chance to Google for "nutter werewolf"?

Technorati Tags: ,

14 November 2007

Weird Rails bug

I Spent some time yesterday tracking down a bizarre bug which was causing some of our Selenium tests to fail. Watching the browser running the tests, I could see that occasionally a page would fail to render, with an "invalid argument" error and a stack trace. The line in question was an <%= end_form_tag %> in a layout. The strange thing was, it didn't display the same behaviour when I ran the single failing test on its own, or when I viewed the page myself.

Or at least, I thought it didn't. Because it seemed intermittent, I tried reloading the page a few times, and sure enough, the error appeared. Once. Then the page reloaded successfully six times, before failing again. This was completely repeatable – six times OK; one stack trace. Regular as clockwork.

Completely stumped, I thought I might as well at least replace the deprecated <%= start_form_tag %> … <%= end_form_tag %> with <% form_tag do %> … <% end %>, and lo and behold, that fixed it.

Unfortunately, I have no idea why. An imaginary prize to whoever can explain it!

5 October 2007

Rails, SOAP and REST

From the list of new features coming in Rails 2.0:

It’ll probably come as no surprise that Rails has picked a side in the SOAP vs REST debate. Unless you absolutely have to use SOAP for integration purposes, we strongly discourage you from doing so.

4 July 2007

Correct use of the flash in Rails

I don't know whether this has caught anyone else out, or whether we just didn't read the documentation properly (it's covered briefly on p153 of AWDwR), but I thought I'd mention it anyway.

Anyone who's written a Rails app will know that the 'flash' is used to store error and status messages, usually on form submissions. Model validation failure messages automatically get copied into the flash, but you often want to do it manually too.

RUBY:
  1. flash[:notice] = "User Details updated."
  2. redirect_to edit_user_path(@user)

The gotcha comes when you want to display a message and render a page, as opposed to redirecting – for example when errors are preventing a form from being submitted. This is how not to do it:

RUBY:
  1. flash[:error] = "Password doesn't match confirmation." # WRONG!
  2. render :action => 'change_password'

The problem is that the flash is stored for the next request. Because we're no longer doing a redirect, that means the message may appear wherever the user goes next, not just on the page that we just rendered. To avoid this, use flash.now, which is only used for the current request:

RUBY:
  1. flash.now[:error] = "Password doesn't match confirmation."
  2. render :action => 'change_password'

The rule of thumb is to use flash if you're redirecting, and flash.now if you're rendering (either explicitly, or by dropping through to the default view for the action).

All very well, but whatever you put in flash.now is cleared out at the end of the request, so how do you test it? The answer (for RSpec, at least) lies in a comment on this RSpec feature request – basically just add the following to spec_helper.rb:

RUBY:
  1. module ActionController
  2.   module Flash
  3.     class FlashHash
  4.       def initialize
  5.         @hash = {}
  6.         @now_hash = {}
  7.       end
  8.    
  9.       def [](key)
  10.         @hash[key]
  11.       end
  12.    
  13.       def []=(key, obj)
  14.         @hash[key] = obj
  15.       end
  16.    
  17.       def discard(k = nil)
  18.         initialize
  19.       end
  20.    
  21.       def now
  22.         @now_hash
  23.       end
  24.    
  25.       def update(hash)
  26.         @hash.update(hash)
  27.       end
  28.      
  29.       def sweep
  30.         # do nothing
  31.       end
  32.     end
  33.   end
  34. end

You can now do something like this:

RUBY:
  1. describe "When a user tries to change his password with an invalid verification code" do
  2.   ...
  3.  
  4.   it "should put an error message in the flash" do
  5.     flash.now[:error].should == "Incorrect verification code or password."
  6.   end
  7.  
  8.   it "should not persist the flash" do
  9.     flash[:error].should be_nil
  10.   end
  11. end

Technorati Tags: , , ,

3 June 2007

Opiniated software

DHH talking about pluralisation in Rails, in Scott Hanselman's RailsConf interview with him and Martin Fowler:

...it was kind of a firewall. It was a firewall for aesthetics. So if you could not appreciate why we did this, why we chose to go through all of this work to get prettier code, maybe you weren't in the state of mind that was a good fit for this community. So we tried to weed people out in some sense – if they don't share the same cultural bias, if they don't share the same values, then maybe they're not a good fit for the Rails community.

It's often said that Rails makes it very easy to Do The Right Thing, whether it's separation of concerns, unit tests, DRY or whatever. I wonder how many people start using better practices because Rails pushes them in the right direction, or whether they choose Rails because they see the obvious evidence of good practices its philosophy and architecture.

Technorati Tags: , , , ,

14 May 2007

Hi, I’m Ruby on Rails…

The guys over at Rails Envy have created an excellent J2EE vs Rails parody of Apple's Get a Mac adverts:

Apparently there are more coming over the next few days.

28 April 2007

Are we spending more and more time writing tests?

A while ago I wrote about testing trivialities, and claimed that no matter how simple the piece of code is, it still ought to have a test. I followed it up with some thoughts on using a helper to simplify writing specs for common validations. Even using the helper, the actual test code for a single validation outweighs the production code by a factor of more than three:

Read the rest of this entry »