Random Ramblings

There are a few times, not many, when you really don't want to trigger AR callbacks on a save. Take the following simple example:

class Article < ActiveRecord::Base
  include ActionView::Helpers::SanitizeHelper
  before_save :sanitize_body_text

  def sanitize_body_text
     self.body_text = sanitize(self.body_text)
  end
end

article.update_attribute(:posted_at, Time.now - 100)

You probably don't want to fire up an expensive method like sanitize when updating the posted_at time.

save_without_callbacks solves that problem.

To Install

./script/plugin install https://tangofoxtrot.com/svn/plugins/save_without_callbacks

On any AR.object that you want to skip the callbacks for:

@something.skip_callbacks = true

*note you cannot set this on mass assignment*

Then call:

@something.save

This plugin can be potentially dangerous! Make sure this is the behavior you want.

For example acts_as_list:

before_create  :add_to_list_bottom
before_destroy :remove_from_list

def remove_from_list
  if in_list?
    decrement_positions_on_lower_items
    update_attribute position_column, nil
  end
end

If you set skip_callbacks to true and updated the position or created/destroyed an object the positions will be off.

This is best used in a situation where you are updating some arbitrary, non relationship, data.

If you are new to rails you've probably seen the method alias_method_chain but dont know exactly what it does. Here is simplified example.

require 'rubygems'
require 'active_support'

class Breakfast
  def cereal
    "Lucky Charms"
  end
end

Produces:
irb(main):003:0> Breakfast.new.cereal
=> "Lucky Charms"

Nothing exotic here. Just a breakfast class with one method. Lets bring in alias_method_chain.

For that we will need to have a method to 'alias to'.

module Milk
  
  def self.included(base)
    base.alias_method_chain :cereal, :milk
  end
  
  def cereal_with_milk
    "Milk and #{cereal_without_milk}"
  end
  
end

The previous code does the following:

  1. Creates an alias (think shortcut) to the method 'cereal' with the name 'cereal_without_milk'
  2. Creates another alias for cereal_with_milk with the name 'cereal'
  3. Defines the method cereal_with_milk

Now when we call the method breakfast.cereal our newly created action, 'cereal_with_milk' will be called. The code in action:

irb(main):002:0> Breakfast.send(:include, Milk)
=> Breakfast
irb(main):003:0> Breakfast.new.cereal
=> "Milk and Lucky Charms"

The end result, we have milk with our Lucky Charms.

Download the original Code: alias_method_chain_example.rb

Xhr Error Catching

February 7th, 2008

One of the more common questions I see from new rails developers is "Clicking an ajax link doesnt do anything." Most web developers use the web developer toolbar extension for firefox (Here). Even then its easy to miss the error message that pops up in console.


I created a simple plugin which will check to see if you made an xhr request, if so it will render the error to a file then bring up a javascript confirm box asking if you want to see the error.

Should be a drop in replacement for rails 2.0.2 and 1.2.6.

script/plugin install http://tangofoxtrot.com/svn/plugins/xhr_rescue_handler

This is my first plugin so please feel free to tear it apart.