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 keyIS NULL
. This is not what you want. To prevent this behavior, you can useunsaved_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
Posted by Dominik Schöler to makandra dev (2013-03-13 09:38)