Exceptional Rails Handling


When I am writing a Rails application it starts out simple with a few if @something.save lines that are pretty self explanatory. Then the application grows and starts to become hairy. Take my contrived example with a grain of salt as I can’t show you production code that I am using.

# app/controllers/widgets_controller.rb
class WidgetsController < ApplicationController

  #
  # Other methods go here
  #

  def something
    # Maybe we handle the update in a special way
    widget = Widget.find(params[:id])
    widget.some_method(params[:widget])

    # for the sake of simplicity let's change the owner
    foobar = widget.foobar
    foobar.owner = current_user

    respond_to do |format|
      if widget.save
        if foobar.save
          format.html { redirect_to widgets_path, :notice => 'Huzzah!' }
        else
          widget.some_special_rollback
          format.html { redirect_to widgets_path, :notice => "You're a moron" }
        end
      else
        format.html { redirect_to widgets_path, :notice => "Not even close"}
      end
    end
  end

end

What did we learn here? Terribly contrived examples can prove anything, No! Though I liked how easy it was to come up with it but that is not why I wrote the code above. I have seen applications get to that point and when I see it now I start to shake my fist violently at the computer and wonder just what in the world were they thinking.

After watching [Avdi Grimm][exceptional-ruby] give his excellent opinion on how you can leverage exception handling in Ruby. I really suggest you go and check it out at the end of this post.

Ruby offers a nice way to handle exceptions with the begin and rescue blocks but I really don’t like how begin can start to clutter your code up. As Grimm has stated, “It can be considered code smell”, and as such should be avoided as much as possible

The other feature that Ruby offers in regards to exception handling is that you can define the rescue part at the bottom of the method. This can be extremely advantageous when trying to organize your code. Let me demonstrate a simple example that we see all the time from the rails generator

# app/controllers/widgets_controller.rb
class WidgetsController < ApplicationController

  def update
    @widget = Widget.find(params[:id])
    @widget.update_attributes(params[:widget])
    @widget.save! # Throw exception if save failed

    respond_to do |format|
      format.html { redirect_to widgets_path, :notice => "It worked" }
    end
  rescue
    # Oh no, the save failed...handle all rollback issues here
    respond_to do |format|
      format.html { render :action => :new }
    end
  end
end

Again the example above is really dead simple but it does demonstrate the point that you can keep your error handling code separated from your non-error code. Now I have found times where I created two models and a third failed to be created and I needed to rollback the changes and set a few of parent’s attributes. This is a case where the transaction block can be used.

# app/controllers/invite_controller.rb
def confirm
  @user = User.find_by_token(param[:token])
  if @user
    Widget.transaction do
      wg = WidgetGroup.create!(:name => "#{@user.name} First Group")
      Widget.create!(:name => "My first widget", widget_group_id => wg.id)
      Widget.create!(:name => "this is a special widget", widget_group_id => wg.id, :special => true)
    end
    redirect_to widget_group_path(wg), :notice => 'Awesome'
  else
    redirect_to root_url, :notice => "This is a terrible app"
  end
end

Transactions are handy and can save you a big head ache. In Computer Science we were always told to keep our memory leaks to a minimum and close all unused file descriptors and other various clean up tasks which would lead me to have special cases where I would have to tear down each object in reverse order from where the error happened. A massive pain if the error happened 4 levels deep.

Where as with transactions, would just rollback the changes and I would be a happy puppy.

Below is Avdi Grimm’s presentation on exeption handling in Ruby and what can be done to clean up code and is an all around way to make yourself more educated on Ruby. Take a look.

Resources

  • [Exceptional Ruby][exceptional-ruby] [exceptional-ruby]: http://blip.tv/avdi-grimm/exceptional-ruby-4778405

New Job


Well I transitioned out from my previous job working for Enfocus Solutions to working for ZippyKid. I love my new job and I am super excited to work with a cool team of developers.

I haven’t worked with PHP in over a year and it’s interesting coming back to it from working with Ruby and Java for a while. PHP makes me angry but also makes me happy. After playing with PHP again I started to love some of the old features like die, vardump, and print_r.

The newer features in PHP 5.3 has me excited. Namespaces are spiffy and allows me to modularize my application even further. I also see it as being one step closer to packages being swapped in and out easier. Ruby has gems, which I think PHP is missing.

Effective Programming


I’ve been programming for the last 6 years and I have a bunch of programming languages under my belt. But just because I know other languages doesn’t make me a desireable programmer. Any decent programmer can pick up a new language within a few weeks and pick up the new programming paradigms after. What makes me desireable is how effective I am when I program.

You need to be effective else you risk being left behind

Break your task up

Programming isn’t something you just start hacking away. Without a game plan you are looking at cornering yourself between getting burnt out or getting stuck on a problem. An ice sculptor doesn’t start just hacking away at a peice of ice expecting something to come from it. An artist doesn’t just start throwing paint on a canvas without having an idea of what they want to convey.

As such you should have a plan.

  1. Install rails
  2. Build SAAS application
  3. ????
  4. Profit

This plan does not work… I really shouldn’t have to explain why. If I was to build a project management application this is how I would initially make my checklist of stuff to do

  • Welcome page
  • User Sign Up
  • Setup Payment System
  • Project Creation
  • Project Update
  • Task Creation
  • Task Completion
  • Due Dates
  • User assignments
  • Time tracking

As you can see the points are generic and scoped as such that you could tackle each point almost within an hour. This is how I divide my tasks up and how I can get my stuff done. You should check out http://asana.com to keep your checklists in order. It’s fairly simple and you can play mutliplayer todo list tackling.

Manage your time

Don’t procrastinate. If it’s a tough problem that needs to be solved for the rest of the team to move forward. It doesn’t make sense to put that problem off until later since other developers are waiting on you.

Break the problem up, put a deadline goal on your task. If you can offload some of the hard work to someone else while you tackle another issue.

Take a break

It is better to be effective than stubborn. It’s a no brainer. I’ve seen people tackle the same problem for hours on end with little to no progress. If you’ve been to a University for a computer science course, I can almost guarantee that you have done a homework assignment that took a large amount of time to solve a problem.

Stop that! It’s a giant waste of time. Get up and go do something else and come back to the problem later. Be effective, not a hinderance.

Ask for help

You are only human, you can’t solve every problem by yourself. Sometimes telling someone your problem will actually solve it. I hang around on some IRC channels and ask for help. This doesn’t mean that you go and mooch off of other developers. No body likes a leech.

Be effective!