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 中的大小、长度和计数没有区别,不是吗?
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 中的大小、长度和计数没有区别,不是吗?
长度将加载所有对象只是为了计算它们;就像是:
select * from addresses...
然后返回结果计数。你可以想象 - 这是糟糕的表现
计数只会发出
select count(*) from addresses...
哪个更好,因为我们加载所有地址并不是为了计算它们
size更智能 - 它会检查关联是否已加载,如果为 true,则返回长度(不调用数据库)。
如果您的用户模型中有一个名为address_count的字段, size还会检查counter_cache,然后 size 将使用该字段进行计数,因此无需在地址表上发出计数。
如果全部失败,sizeselect count(*)
将在数据库上发出
1) 在 rails count 是一个 ActiveRecord 方法,因此 count 可以直接应用于模型名称:
> User.count
(1.4ms) SELECT COUNT(*) FROM "users"
=> 1
但是 size 不是 ActiveRecord 方法,因此它会抛出错误
> User.size
"NoMethodError".
2) Rails 中的大小可以与 ActiveRecord 数组一起使用(即 size 是 Array 方法)
> User.all.size
(1.2ms) SELECT COUNT(*) FROM "users"
=> 1
3) count 将始终触发 ActiveRecord 查询。但 size 不会触发 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
如果“地址”是一个看起来像的关联,那么它们是不同的,但它们应该返回相同的结果。
#count 由 ActiveRecord 提供,将执行类似“select count(*) from addresses where user_id =”之类的操作。
在其他情况下,#addresses 将构建一个包含实际模型对象的数组,并且 #size 和 #length 由 Array 类或 Enumerable 提供。
所以#count 可能更快,因为计数发生在数据库中。如果您确实需要地址,那就不好了:)