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