ActiveRecord の pluck, Ruby の map の違いと使い分け
こんにちは、ラブグラフエンジニアの Daichi です!
アプリケーション開発をしていると、DBから任意のカラムの値のみを取得したい場合があるかと思います。
そんな時に ActiveRecord の pluck か Ruby の map メソッドを利用するかと思いますが、
皆さんはその違いを意識されていますか?私は意識出来ていませんでした。
そのため、今回の記事ではこの2つのメソッドの違いや使い分けをまとめていこうと思います。
対象読者
- 出力内容が同じ以下2つの実装の内部挙動や違いが思い浮かばない方
- pluck と map をなんとなく利用している方
Staff.all.pluck(:name)
Staff.all.map(&:name)
pluck
ActiveRecord::Calculations のメソッド
引数としてカラム名のリストを渡すと、指定したカラムの値の配列を、対応するデータ型で返してくれます。
# SELECT `staffs`.`name` FROM `staffs`
Staff.all.pluck(:name)
# => ["太郎","花子","治郎"]
データベースから直接値を取得してくれ、 ActiveRecord オブジェクトのインスタンス化を行わないため、
メモリ使用量が少なく、大量のデータを扱う場合はパフォーマンスが高いです。
ただ、メソッド実行時に毎回 SQL 文が発行されてしまいます。
注意点としては、オーバーライドを利用するメソッドにも利用できないことと、pluck を利用した後にスコープチェーンを利用できないことがあります。
スコープチェーンを利用したい場合は、 pluck の後に置くのが良さそうです。
map
Ruby の Array#map メソッドのことです。
配列の各要素に対してブロックを評価した結果を全て含む配列を返します。
map メソッドを利用して特定のカラムの値を取得するためには、取り出したいカラム以外の情報も取得しなくてはいけません。これによりメモリ使用量が増えてしまいます。
# SELECT `staffs`.* FROM `staffs`
Staff.all.map(&:name)
# => ["太郎","花子","治郎"]
両者の使い分け
pluck は実行ごとに SQL を発行してしまうので、 SQL の発行回数を気にせず、特定のカラムのみ取得してくる場合に利用することが好ましいです。
逆に繰り返し文の中など、その都度 SQL を発行されたくない場合は map を利用することが好ましいです。
両者の違いを知ることにより、メモリの使用量を減らしたり、無駄な SQL を発行させなくなったりとパフォーマンスを意識したコーディングが可能になります。
この記事が自分と同じように pluck と map の違いを知らなかった方の参考になれば幸いです!
Discussion