Comparison <=> operator on string attributes of ActiveRecord objects

[tweetmeme]
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)
    self.my_attribute.casecmp(other.my_attribute)
  end
end
Advertisements

Overriding fundamental ActiveRecord methods (like destroy) whilst preserving callbacks

[tweetmeme]
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
  end
  freeze
end

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.