Comparison <=> operator on string attributes of ActiveRecord objects

Here’s a little gotcha for you which caught me out by surprise, obvious when you think about it, but irritating if you miss it: the ruby String comparison operator does case-sensitive comparisons.

# Good:
['C', 'b', 'A', 'D'].sort #=> ['A', 'b', 'C', 'D']

# Bad (what <=> gives you out the box):
['C', 'b', 'A', 'D'].sort #=> ['A', 'C', 'D', 'b']

For a nice efficient implementation of a AR model comparitor use the String#casecmp method for a case-insensitive comparison:

class MyObject
  def <=>(other)

Overriding fundamental ActiveRecord methods (like destroy) whilst preserving callbacks

OK, so you’ve decided that it’s a good idea for you to override one of the fundamental methods on one of your ActiveRecord models. But in doing so, you have discovered that all of a sudden your callbacks have stopped working.

The reason for this is when your class is loaded, ActiveRecord::Callbacks have already hooked in the callback methods around the relevant methods using alias_method_chain meaning that the once named destroy method is now called destroy_without_callbacks.

So, to actually override the destroy method, use the following code:

def destroy_without_callbacks
  unless new_record?
    # do your code here

Note that the implementations will differ for other methods e.g. create, so you should check the ActiveRecord base class to see what should be in there.