Archive for the ‘Ruby on Rails’ Category

Why we need to stop designing and start delivering

Lately I’ve been very unproductive. Lost in business discussions and dreaming about the next big thing, I couldn’t finish two paid projects, and that sucks™.

The invisible shackles that didn’t allow me to finish those jobs have been holding me back so that I wasn’t able to do any real work even on personal projects.

I’ve tried finding the cause for this, blaming my lack of self discipline or the fact that I was not doing GTD as strictly as I was six months ago, but I knew there had to be something else, and the whole situation was getting on my nerves.

Last week I bought a game for the Nintendo Wii, Mario Strikers Charged, and while playing I remembered a pet project I started more than an year ago and never completed.

The project name was ICCFriends, a repository of Nintendo Friend Codes for the usenet it.comp.console community.

This time I had to finish it, so I went and looked through my code: awful. There was as much BDUF in there as in Windows Vista, and while wandering through the models and controllers, suddenly I got it!

I knew why I wasn’t delivering: I was designing things that were not useful. I lost so much time preparing for refactoring, or moving code around or laying the ground for future extractions or features that when the time came to implement the real thing I grew tired or got bored.

I then did the only thing I could possibly do to complete ICCFriends:

$ rm -rf ~/src/iccfriends
$ rails ~/src/iccfriends

I then focused on the simplest and shortest set of features I could imagine and in a couple of hours ICCFriends.net was up and running, and with more interesting features than those I was bduffing.

It looks rushed out because it is, but once again I was able to think and deliver and the rush of energies that came with it is a nice feeling I really missed.

Yesterday I learnt an important lesson, and from now on I will always strip my feature list before even start thinking about the implementation.

Xen and the Art of Rails Deployment

Ezra Zygmuntowicz is one of the few recognized masters of Rails deployment. In his talk at RailsConf2007 he pointed out some deployment strategies and some common errors programmers do.

Being a great guy he posted the slides on his blog.

I recommend to go and check them out asap, I did, and I feel a better person now :)

Transaction in Rails

In an application I wrote for a client I needed transactions to handle a batch import of records from a legacy table into different models.

I browsed the documentation, googled for info and even asked in #rubyonrails, but wasn’t able to get any help, so I had to resort to good old trial and error.

First I tried nested transactions (the old way):

FirstModel.transaction do 
  SecondModel.transaction do
    ThirdModel.transaction do
      FourthModel.transaction do
        fourth.do_stuff
        third.save
        second.handle_your_stuff
        first.good_old_foo_bar
      end
    end
  end
end

I had a couple of problems with this code:

  • Ugly
  • Deprecated

It also didn’t seem to work for me, so I banged my head against my laptop for half a hour or so and suddenly the rails documentation started to make sense, so I wrote this code instead:

transaction do
  first.save!
  second.save!
  third.save!
  fourth.save!
end

The reason I used save! was that the documentation says that a transaction block catches exceptions. Unfortunately that’s not true and to make it work I had to remove the exclamation marks.

Now I had another problem. I included the transaction code in a class I put in lib/, ImportJob, and I was using it with script/runner:

script/runner 'ImportJob.run' -e ENVIRONMENT

All of a sudden I started getting method missing errors on transaction. Now I could investigate and do the right thing or just hack a solution – I decided to hack a solution :)

class ImportJob < ActiveRecord::Migration
end

Deriving ImportJob from Migration solved my problems. Now if anyone has a cleaner solution I will be happy to implement it but at least I solved my problem with transactions (and I hope this will be helpful for someone else too).

Update: Tim pointed out some flaws in my code and some more testing revealed that I needed to have an exception to trigger a Rollback, so I modified the block:

begin
  transaction do
    first.save!
    second.save!
    third.save!
    fourth.save!
  end
rescue ActiveRecord::RecordInvalid => invalid
  # do whatever you wish to warn the user, or log something
end

This works fine, thanks Tim!

Environment constraints on Rails Migration

I’m working on a rails application that has to integrate with a legacy system, with its own tables, and was wondering on the best way to have migrations on development and testing to have those tables locally, while ignoring them in production. My good friend and rails superstar Paolo Dona’ has shown me the Rails Environments plugin, that allows you to write code like this:

class CreateLegacyTable < ActiveRecord::Migration
  def self.up
    unless Rails.production?   
      create_table
        ....
    end
  end
end

Nifty, isn’t it?

Drag and Drop deletion with Rails

I don’t like to do Drag and Drop in Web Applications. I dislike it so much that I never did dnd in Rails, so when a customer explicitly asked for a drag and drop trashcan in an application I had to start looking through rails docs, fearing dozens of Javascript callbacks.

It turned out wonderfully easy, requiring me to add just two lines of code in the view and a short action in the controller:

# This is the line of code I added to the partial that is rendered for each draggable element
<%= draggable_element "#{picture.class}_#{picture.id}", :revert => true, :constraint => "'vertical'" %>
 
# This is the code I added to the trashcan 
<%= drop_receiving_element("trash", :url => {:controller => :immobili, :action => :destroy_image}, :hoverclass => "hover_trash") %>

That’s it, really, the controller action just deletes the element and hides is on the page via a render :update block.

Test Driven RJS with ARTS

If you’re like me, you like writing tests for your code. Writing tests is a nice thing to do and saves you a lot of headaches.

Writing tests for Ruby on Rails is really simple, with the wonderful testing framework built in Rails, but things become less ideal when you need to write tests for your RJS code.

This morning I wanted to test the following snippet:

def add_file_field
  render :update do |page|
    page.remove "link_to_add_#{params[:attachment_type]}"
    page.insert_html :bottom,
                     params[:attachment_type],
                     :partial => "#{params[:attachment_type]}_file_field", 
                     :locals => {:index => params[:index].to_i}
  end
end

But the test was failing and I didn’t know why. The ARTS Plugin came to the rescue, allowing me to test the rjs response:

  def test_add_file_field
    xhr(:get, :add_file_field, :index => 1, :attachment_type => "plan")
    assert_response :success
    assert_rjs :remove, "link_to_add_plan"
    # more code here...
  end

Unfortunately that didn’t help with my problem since the cause was not the RJS, I was simply forgetting to login in my setup method :)

Language Redirect, an extension for Radiant CMS

While looking through my email I found an email that helped me remember that a couple of months ago, while working on StudioCarone.it I wrote (ported) a simple extension to the wonderful Radiant CMS, language_redirect_extension. The usage is straightforward, just check it out via svn into your extensions directory.

The rest of the extension works like the old language redirect behavior used to do. Drop me a mail at info AT tempe DOT st if you have any problems or if you need more detailed instructions.