Rails中的大小,长度和计数

时间:2012-09-03 19:46:28

标签: ruby-on-rails ruby

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中的大小,长度和计数没有区别,不是吗?

3 个答案:

答案 0 :(得分:43)

长度会加载所有对象以计算它们;类似的东西:

select * from addresses...

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

计数只会发出

select count(*) from addresses...

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

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

如果您的用户模型中有一个名为 address_count 的字段,

尺寸也会检查 counter_cache ,那么尺寸将使用此字段进行计数,因此无需在地址表上发布计数。

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

答案 1 :(得分:2)

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

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

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

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

答案 2 :(得分:2)

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"
 => #<ActiveRecord::Relation [#<User id: 1, email: "fasf@f.df", 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