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 ではサイズ、長さ、数に違いはありませんね。
lengthは、すべてのオブジェクトをカウントするためだけにロードします。何かのようなもの:
select * from addresses...
結果カウントを返します。ご想像のとおり、パフォーマンスが悪い
カウントが発行されます
select count(*) from addresses...
カウントするためだけにすべてのアドレスをロードするわけではないため、これは優れています。
size の方がスマートです - アソシエーションが既にロードされているかどうかを確認し、true の場合は長さを返します (データベースへの呼び出しを発行しません)。
sizeは、ユーザー モデルにaddress_countという名前のフィールドがある場合、 counter_cacheもチェックします。sizeはこのフィールドをカウントに使用するため、address テーブルでカウントを発行する必要はありません。
すべてが失敗した場合、サイズselect count(*)
はデータベースでa を発行します
1) Rails では count は ActiveRecord メソッドであるため、count は次のようにモデル名に直接適用できます。
> User.count
(1.4ms) SELECT COUNT(*) FROM "users"
=> 1
ただし、サイズは ActiveRecord メソッドではないため、エラーがスローされます
> User.size
"NoMethodError".
2) レールのサイズは ActiveRecord 配列で使用できます (つまり、サイズは Array メソッドです)
> User.all.size
(1.2ms) SELECT COUNT(*) FROM "users"
=> 1
3) count は常に ActiveRecord クエリを起動します。ただし、レコードまたは ActiveRecord 配列が次のように既にロード (実行) されている場合にのみ、size は 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 の方がおそらく高速です。実際にアドレスが必要な場合はあまり良くありません:)