ActiveRecord: count vs size vs length on associations

Updated . Posted . Visible to the public. Repeats.

TL;DR: You should generally use #size to count associated records.

size

  • Counts already loaded elements
  • If the association is not loaded, falls back to a COUNT query

count

  • If a counter cache is set up, returns the cached value
  • Issues a COUNT query else

Caveats

  • If you trigger a COUNT query for an association of an an unsaved record, Rails will try to load all children where the foreign key IS NULL. This is not what you want. To prevent this behavior, you can use unsaved_record.association.to_a.size.
  • count looks directly into the database, neglecting already loaded elements. This becomes a problem when you use that "db count" and process the loaded elements.
    A common example is tests: Imagine a test that sets up a few records and finishes the test setup by asserting a number of associated records. If you use .count for that job, the assertion cannot see that the setup records have loaded (i.e. cached) their associations too early and now are missing elements. Tests relying on the setup will fail, because they will operate on the loaded records. You will hardly notice, because you rely on the assertion. Using .size avoids this problem.

length

  • Loads all records from the database, then returns the number of elements
Dominik Schöler
Last edit
Dominik Schöler
Keywords
has_many, scope, relation
License
Source code in this card is licensed under the MIT License.
Posted by Dominik Schöler to makandra dev (2013-03-13 09:38)