Railsのpluckメソッドって便利だなーの話

#### はじめに
実務でcontrollerからviewへ値を渡すときに悩んでいたら先輩からpluckメソッドを使うといいよと言われました。
プログラミングスクール時代には学習しておらす、実際に使ってみて「あっ便利だ！」と思いましたので備忘録として残したいと思います。
なお、学習のためにcontrollerからviewへ値を渡す際にかなりまわりくどい書き方をしていますのでご了承ください。
おかしな点等は教えていただけるとありがたいです。

#### 環境
Ruby　2.6.5
Rails　6.0.5

#### pluckとは
pluckとは英語で「摘みとる」という意味らしいです。なんか残酷な・・・。
おそらくオブジェクトから値を摘み取っていくということなんでしょうね。
そんなことは置いといて調べてみると

>pluckメソッドとは、引数に指定したカラムの値を配列で返してくれるメソッドです。 
>上記の様にmapメソッドに置き換える事が可能ですが、返り値を配列として取得する場合は、pluckメソッドを使った方がシンプルに記述することが出来ます。

と書かれています。うん、うんそういうことね。なるほどなるほど！

ん・・・？
やっぱりちょっとわかんないのでいろいろと調べてみることにしました。

#### 前提
データを準備します。
productionテーブルを作り値を準備します。
 - seeds.rbに次のように記述し、rails db:seedでDBにデータを登録します。
  ~~~ seeds.rb
  10.times do |n|
    Production.create!(
      name: "mac#{n + 1}世代",
      price: 10000 * (n + 1),
      introduction: "#{n + 1}世代です",
      made_in: "japan",
      condition: "good"
    )
  end 
  ~~~
きちんと登録されてそうです。
[![Image from Gyazo](https://i.gyazo.com/75dbee695f0bb4842142e1504a2f28ed.png)](https://gyazo.com/75dbee695f0bb4842142e1504a2f28ed)

#### いろいろやってみる
pluckメソッドの表記は次にように記述します。
~~~ruby
 モデル名.pluck(第一引数, 第二引数, ・・・)
~~~
引数は第三引数、第四引数ともっととることができます。
その分値を（摘み）取ってくることが可能です。

今回の例でいくなら
~~~ruby
 Production.pluck(:name, :price)
~~~
のような形になります。
引数には自分がとってきたいカラム名が入ります。この時シンボルにするのを忘れないでください。
具体的にどんな挙動になるか見ていきましょう。
rails consoleで試してみます。

- 通常通りallで値を取得
~~~ruby
　pry(main)> Production.all
Production Load (0.3ms)  SELECT `productions`.* FROM `productions`
=> [#<Production:0x00007fbe64d90c18
  id: 1,
  name: "mac1世代",
  price: 10000,
  introduction: "1世代です",
  made_in: "japan",
  condition: "good",
  created_at: Sun, 26 Jun 2022 20:35:06 UTC +00:00,
  updated_at: Sun, 26 Jun 2022 20:35:06 UTC +00:00>,
 #<Production:0x00007fbe661e74f0
  id: 2,
  name: "mac2世代",
  price: 20000,
  introduction: "2世代です",
  made_in: "japan",
  condition: "good",
  created_at: Sun, 26 Jun 2022 20:35:06 UTC +00:00,
  updated_at: Sun, 26 Jun 2022 20:35:06 UTC +00:00>,
 #<Production:0x00007fbe661e7428
  id: 3,
  name: "mac3世代",
  price: 30000,
  introduction: "3世代です",
  made_in: "japan",
  condition: "good",
  created_at: Sun, 26 Jun 2022 20:35:06 UTC +00:00,
  updated_at: Sun, 26 Jun 2022 20:35:06 UTC +00:00>,
:(続く)
~~~
とすべての値を取得しました。
では、pluckメソッドを使ってnameの値だけをとってきたい場合は次のようにします。
- pluckメソッドでnameの値だけ取得
~~~ruby
 Production.pluck(:name)
~~~
実行結果です。
~~~ruby
pry(main)> Production.pluck(:name)
(0.4ms)  SELECT `productions`.`name` FROM `productions`
=> ["mac1世代", "mac2世代", "mac3世代", "mac4世代", "mac5世代", "mac6世代", "mac7世代", "mac8世代", "mac9世代", "mac10世代"]
~~~
無事に全ての値からnameの値だけを配列として取ってくることができました。
次に引数を増やし、priceの値も取ってきたいと思います。

- pluckメソッドでnameとprice値を取得
~~~ruby
Production.pluck(:name, :price)
~~~
実行結果です。
~~~ruby
pry(main)> Production.pluck(:name, :price)
(0.4ms)  SELECT `productions`.`name`, `productions`.`price` FROM `productions`
=> [["mac1世代", 10000],
 ["mac2世代", 20000],
 ["mac3世代", 30000],
 ["mac4世代", 40000],
 ["mac5世代", 50000],
 ["mac6世代", 60000],
 ["mac7世代", 70000],
 ["mac8世代", 80000],
 ["mac9世代", 90000],
 ["mac10世代", 100000]]
~~~
全ての値からnameとpriceの値だけを配列として取ってくることができました。
ちなみに話からずれてしまうのですがこの配列をハッシュにするにはto_hメソッドを使うと便利です。
~~~ruby
pry(main)> Production.pluck(:name, :price).to_h
(0.5ms)  SELECT `productions`.`name`, `productions`.`price` FROM `productions`
=> {"mac1世代"=>10000,
 "mac2世代"=>20000,
 "mac3世代"=>30000,
 "mac4世代"=>40000,
 "mac5世代"=>50000,
 "mac6世代"=>60000,
 "mac7世代"=>70000,
 "mac8世代"=>80000,
 "mac9世代"=>90000,
 "mac10世代"=>100000}
~~~
このように値をハッシュにすることができました。
実際にcontrollerに記述してviewに送ることができそうです。
~~~ productions_controller.rb
class ProductionsController < ApplicationController
  def index
    ＠productions_name_and_price = Production.pluck(:name, :price).to_h
  end
end
~~~
controllerで定義したデータをハッシュにしてviewファイルに送り表示させます。
~~~ production.html
<div class="test">
  <div class="test_name">
    値段：<%= @productions_name_and_price[:"mac6世代"] %>円
  </div>
</div>
~~~

[![Image from Gyazo](https://i.gyazo.com/6ce34605f64f6aa2bcd5a75b9e538273.png)](https://gyazo.com/6ce34605f64f6aa2bcd5a75b9e538273)

無事にブラウザに表示されました。
pluckメソッドはmapメソッドと比べDBからデータの呼び出し方違うので、パフォーマンス的にも良いそうです。

#### 気を付けること
pluckメソッドはクエリを直接トリガするので、その後ろに他のスコープをチェインすることはできないようです。
~~~ruby
Production.pluck(:name).limit(1)   
~~~
これはエラーになる。

#### おわりに
実際にはもっと簡単に表示させることができますが、今回はあえてpluckメソッドを用いて、viewに表示させてみました。どんな動きかを理解することってとても難しいです。これから実務の中でしっかり学んで一つ一つ理解していきたいと思います。

#### 参考記事
https://qiita.com/k-o-u/items/31e4a2f9f5d2a3c7867f

https://pikawaka.com/rails/pluck