【Ruby on Rails】present?とexists?
ActiveRecordで条件に合致するレコードが存在するかをチェックする際にpresent?を使うよりもexists?を使うようにした方が良さそう。
present? の方は active_support/core_ext のコード。
Active Record で定義されているメソッドではなく、 (データベース非依存の) Active Support で定義されているメソッドであり、present? のレシーバーとなる ActiveRecord_Relation のクエリ結果のオブジェクトに対して、present? が呼び出されている。
exists? は active_record/relation で定義されているメソッド。クエリ発行を前提とした処理になっていて、存在確認用のクエリとして組み立てて発行した結果をもとに返す。
つまり、present?をActiveRecord_Relationのクエリ結果のオブジェクトに対して適用すると条件に該当するレコード全てをDBから取得して評価することになってしまう。
exists? は存在確認のためのクエリの結果を boolean で返す。present?とは発行されるクエリが異なり、DBレベルでtrueまたはfalseを返してくれる。
code:ruby
irb(main):005> Comic.where(publisher_id: 1).present?
Comic Load (0.2ms) SELECT "comics".* FROM "comics" WHERE "comics"."publisher_id" = ? "publisher_id", 1
=> true
irb(main):006> Comic.where(publisher_id: 1).exists?
Comic Exists? (0.4ms) SELECT 1 AS one FROM "comics" WHERE "comics"."publisher_id" = ? LIMIT ? "publisher_id", 1], ["LIMIT", 1
=> true