Red Green Repeat Adventures of a Spec Driven Junkie

TWIL: Ruby's other meaning for <

tl;dr: < can also mean .subclass_of?(Class) in Ruby

I was working with a group of objects and I only wanted items which returned an ActiveRecord_Relation to have another message sent. The relation are all a subclass of different models: Model_x::ActiveRecord_Relation, Model_y::ActiveRecord_Relation, Model_z::ActiveRecord_Relation, etc.

My first solution:

object.send_message if object.class.to_s.split('::').last == 'ActiveRecord_Relation'

which definitely works, but really messy since the class is being converted to a string then comparison operations are done on it. I tried a few more things to get this to work:

1
2
3
4
5
object.class # => Model_x::ActiveRecord_Relation
object.class.is_a?(ActiveRecord) # => false
object.class.is_a?(ActiveRecord::Base) # => false
object.class.is_a?(ActiveRecord_Relation) # => NameError: uninitialized constant ActiveRecord_Relation
object.class.is_a?(Model_x::ActiveRecord_Relation) # => false

But I could never get the evaluation I want, without resorting to string comparisons (hence, the first solution.)

A better programmer showed me a

object.class < ActiveRecord_Relation

which, I found out in Ruby < can mean: object.subclass_of?(Class). Mind: blown.

This is probably the best solution since it uses Ruby’s own method to test whether an object is a subclass of another or not.

< is very easy to over look in Ruby code (and VERY hard to Google!) as it is used in many other places in Ruby, like:

Model < ActiveRecord::Base

which has a very different meaning than .subclass_of?(Class). :-D

Stay spec-ing my friend.