Rails中的大小,长度和计数

1.9.3p194 :002 > u = User.find_by_email("email@mail.ru") 1.9.3p194 :005 > u.addresses.size => 1 1.9.3p194 :006 > u.addresses.length => 1 1.9.3p194 :007 > u.addresses.count 

Rails 3.2.3中的大小,长度和计数没有区别,不是吗?

length将加载所有对象以计算它们; 就像是:

 select * from addresses... 

然后返回结果计数。 你可以想象 – 这是糟糕的表现

伯爵只会发出

 select count(*) from addresses... 

这是更好的,因为我们没有加载所有地址只是为了计算它们

size更聪明 – 它将检查关联是否已加载,如果为true则返回长度(不发出对数据库的调用)。

如果您的用户模型中有一个名为address_count的字段, size也会检查counter_cache ,那么size将使用此字段进行计数,因此无需在地址表上发出计数。

如果全部失败, size将在数据库上发出select count(*)

如果“地址”是它看起来的关联,那么它们是不同的但它们应该返回相同的结果。

#count由ActiveRecord提供,并将执行类似“select user(*)from user_id =”的地址。

在其他情况下,#addresses将构建一个包含实际模型对象的数组,#size和#length由Array类或Enumerable提供。

所以#count可能更快,因为计数发生在数据库中。 如果你真的需要地址,那就不太好了:)

1)在rails中,count是一个ActiveRecord方法,因此count可以直接应用于模型名称:

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

但是大小不是ActiveRecord方法,因此会抛出错误

 > User.size "NoMethodError". 

2)rails中的大小可以与ActiveRecord数组一起使用(即size是Array方法)

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

3)count将始终激活ActiveRecord查询。 但只有当记录或ActiveRecord数组已经加载(执行)时,大小才会触发ActiveRecord查询:

  > d=User.all User Load (18.1ms) SELECT "users".* FROM "users" => #]> 2.3.3 :009 > 2.3.3 :010 > d.count (1.3ms) SELECT COUNT(*) FROM "users" => 1 2.3.3 :011 > d.size => 1