18
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

rails6から追加される`ActiveRecord::Relation#pick`について

Posted at

ユースケース

たとえば、年齢20歳以上絞り込んだユーザー1人のidを取得したいとき

よくある書き方

以下のように書くことでidが取得できますが、この書き方だとパフォーマンスが悪くなる事もあります。

User.where("age > 20").pluck(:id).first

この処理を行った場合、以下の処理が実行されます。

  1. whereでレコードを絞り込み
  2. users.idのリストをアプリケーションに返す
  3. users.idのリストからArrayを生成
  4. 生成したArrayに対しrubyのArray#firstで1件抽出する

この場合、アプリケーションで1件しかデータを使用しないのにDBは該当する全てのデータを返すので余計な処理やリソース消費が発生します。

対応

limit句を使用してあげます。
limit句を指定する事でDBはレコードを1件見つけた時点で検索を止めて結果を返すので高速になります。(全ての場合に高速になる訳ではありません。)

- User.where("age > 20").pluck(:id)).first
+ User.where("age > 20").limit(1).pluck(:id)).first

rails6から追加されるActiveRecord::Relation#pick

上の.limit(1).pluck(:id)).firstのショートハンドがrails6のpickメソッドです。
このメソッドを使用する事でさらに簡潔にコードを記述する事ができます。

- User.where("age > 20").limit(1).pluck(:id)).first
+ User.where("age > 20").pick(:id)

実装を確認する

そのまんま

activerecord/lib/active_record/relation/calculations.rb
def pick(*column_names)
  limit(1).pluck(*column_names).first
end
18
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?