Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

size, length and count in Rails

1.9.3p194 :002 > u = User.find_by_email("[email protected]")
1.9.3p194 :005 > u.addresses.size
 => 1 
1.9.3p194 :006 > u.addresses.length
 => 1 
1.9.3p194 :007 > u.addresses.count 

There is no difference between size, length and count in Rails 3.2.3, isn't it?


2 Answers

length will load all your objects just to count them; something like:

select * from addresses...

and then return the results count. As you can imagine - it's bad performance

count will just issue

select count(*) from addresses...

which is better, because we are not loading all addresses just to count them

size is smarter - it'll check if the association is already loaded and if true then return the length (without issuing a call to the database).

size also checks for counter_cache if you have a field named address_count in your user model, then size will use this field for the count, so there is no need to issue a count on the addresses table.

if all fails, size will issue a select count(*) on the database

like image 119
Chen Fisher Avatar answered Sep 10 '25 03:09

Chen Fisher


1) In rails count is a ActiveRecord method, therefore count can be applied on model name directly as:

> User.count
   (1.4ms)  SELECT COUNT(*) FROM "users"
=> 1

But size is not ActiveRecord method therefore it will throw an error

> User.size
"NoMethodError".

2) Size in rails can be used with ActiveRecord array (ie. size is Array method)

> User.all.size
   (1.2ms)  SELECT COUNT(*) FROM "users"
=> 1 

3) count will always fire ActiveRecord query. but size will not fire ActiveRecord query, only if record or ActiveRecord array is already loaded (executed) as:

  > d=User.all
  User Load (18.1ms)  SELECT "users".* FROM "users"
 => #<ActiveRecord::Relation [#<User id: 1, email: "[email protected]", name: "mano", dob: "2017-02-16", address: "fasfafasf", created_at: "2017-02-12 08:16:12", updated_at: "2017-02-12 09:34:07", online: false>]> 
2.3.3 :009 > 
2.3.3 :010 >   d.count
   (1.3ms)  SELECT COUNT(*) FROM "users"
 => 1 
2.3.3 :011 > d.size
 => 1 
like image 29
Manoj Datt Avatar answered Sep 10 '25 01:09

Manoj Datt