Active Recordのスコープではpresent?ではなくexists?を使う

present? の弊害

Active Relationに対して present?を使うとパフォーマンス低下を招くことがある

Rails: ActiveRecordのスコープでpresent?を使うとパフォーマンスが落ちることがある(翻訳)|TechRacho by BPS株式会社

上記の記事の例を引用

books = Book.recently_released
if books.present?
  books.paperbacks.each { |book| puts book.title }
end

Active Relationに対して present? を使うと、該当するレコードをすべてDBから取得し、メモリの配列に読み込んだ上で配列が空かチェックされる。

すでにオブジェクトがメモリに読み込まれているのであれば、 prensent? を使うことによりパフォーマンスが低下することはない

存在チェックするだけならレコードが1つでもあることが確認できればよく、すべてのレコードを取得する必要は無い

レコード数が多い分だけDBからの取得とメモリへの読み込みが行われるため、パフォーマンスに影響する可能性が考えられる

ではどうするか

any? メソッド やexists? メソッドを使う。

これらのメソッドを使うとクエリに LIMIT 1 の指定がつき、レコードが1件でも存在すればそこで検索を終了する。

また、存在チェックをするだけでオブジェクトをメモリに展開しない。

books = Book.recently_released
if books.any?
  books.paperbacks.each { |book| puts book.title }
end

【参考記事】