count vs length vs size

— February 27, 2008 at 14:14 PST


In Ruby, #length and #size are synonyms and both do the same thing: they tell you how many elements are in an array or hash. Technically #length is the method and #size is an alias to it.

In ActiveRecord, there are several ways to find out how many records are in an association, and there are some subtle differences in how they work.

  • post.comments.count - Determine the number of elements with an SQL COUNT query. You can also specify conditions to count only a subset of the associated elements (e.g. :conditions => {:author_name => "josh"}). If you set up a counter cache on the association, #count will return that cached value instead of executing a new query.
  • post.comments.length - This always loads the contents of the association into memory, then returns the number of elements loaded. Note that this won't force an update if the association had been previously loaded and then new comments were created through another way (e.g. Comment.create(...) instead of post.comments.create(...)).
  • post.comments.size - This works as a combination of the two previous options. If the collection has already been loaded, it will return its length just like calling #length. If it hasn't been loaded yet, it's like calling #count.

That's I always have to look up these differences, so now I have them in one place so I don't have to think about it anymore.

By the way, today is my blog's second birthday. I just couldn't let that go by without a post!

14 commentsassociations, rails

Comments
  1. labria2008-02-27 15:03:17

    Congrats with the birthday =)

    So, if I call .size it will do a SQL COUNT if the collection is not loaded, right?

  2. omygawshkenas2008-02-27 18:03:14

    That can't be true, can it?

    Doesn't post.comments grab the comments from the database, regardless of whatever methods you're going to call on those comments later? Aren't you talking about the ActiveRecord class method, like Comment.count()?

  3. IceskYsl2008-02-27 18:08:03

    Josh ,Congrats with the birthday .

  4. Don2008-02-27 18:29:11

    omygawshkenas,

    "comments" is actually an AssociationCollection object, which won't actually load the records unless it absolutely needs too (unless I'm totally high). Search for "size" in this file to see the method and how it works.

  5. Nate Klaiber2008-02-27 18:42:38

    @omygawshkenas I think Don is correct with this one. Associations are instantiated lazily, so are only used when needed (correct me if I am wrong).

    So, is it blog.hasmanythrough.com.lenth == 2 or blog.hasmanythrough.com.size == 2 ? hehe. Congrats on the second birthday.

  6. Josh Susser2008-02-27 19:08:33

    @omygawshkenas: As Don and Nate have said, post.comments returns an AssociationProxy object. The proxy has a small number of methods like #length and #reset and #loaded? that you can use to work with the association itself, but it mostly forwards messages on to its target. For collections (has_many, habtm), that's an array of the contents.

  7. mikong2008-02-27 19:53:59

    Happy Birthday!

    I've learned a lot from this blog. Keep those posts coming :)

  8. omygawshkenas2008-02-27 21:09:14

    Wow. Every time you underestimate it, you find out just how smart Rails can be. Thanks for the correction.

  9. Dominiek2008-02-28 04:44:57

    Excellent!

    Here is some additional info about using the counter cache as well:

    http://dominiek.com/articles/2007/12/11/optimizing-rails-quick-and-dirty

  10. Mislav2008-02-28 08:04:56

    Nice post, it's good to be aware of the differences! I always knew there were, but never really bothered to look it up.

  11. Coty2008-02-28 13:38:45

    Thanks for pointing this out, Josh. After reading James Mead's post on length vs. size, I've favored using length in general. Of course, with ActiveCollection I would use count when I didn't want to force a data load. Thanks for pointing out that size is more than an alias in the ActiveCollection case. It will come in handy.

    Oh, and congrats on the two years of blogging.

  12. Brian2008-02-28 14:29:42

    Hi Josh,

    Congrats on the 2nd birthday of your blog. Great job as always !

    Brian

  13. roller82008-03-24 15:41:26

    Happy 2nd birthday! Thanks for this always helpful blog!

  14. Dirk2008-04-19 10:27:22

    Happy birthday! :)

Sorry, comments for this article are closed.