A little too much help

None of this (short) post is meant to impugn the usefulness of ActiveRecord. But this is a bug waiting to happen. (Or “was”, given that it had me smacking my forehead like a dolt IRL about a month ago.)

In Ruby, Array#length and Array#count are generally expected to behave similarly. (#count can take a block to filter the total, but with no arguments, they both tell you how many things are in the array. Simple enough.) ActiveRecord (mostly) helpfully makes its non-array return values look like arrays. That is: when you do this…

records = Model.where(attr: "has_some_value")

…AR consipires to allow records to work like an array. It is of course actually an instance of ActiveRecord::Relation, for reasons having to do with lazy evaluation of SQL queries, and this is generally pretty badass. Except when ActiveRecord::Relation#count doesn’t actually behave like Array#count:

# how many there are in the db
records.length 
=> 20
records.count
=> 20
# but we can add some arbitrary object to this "array"---AR will not complain about this:
records << Object.new
# this shows the updated cardinality of our "array"
records.length 
=> 21
# ...but this calls an actual "SELECT COUNT" on the db, so it doesn't understand we added something
records.count
=> 20

Manifestly, this is not the end of the world. But remember not to treat these methods as synonymous when dealing with ActiveRecord.