はじめに
実務で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にデータを登録します。
10.times do |n|
Production.create!(
name: "mac#{n + 1}世代",
price: 10000 * (n + 1),
introduction: "#{n + 1}世代です",
made_in: "japan",
condition: "good"
)
end
いろいろやってみる
pluckメソッドの表記は次にように記述します。
モデル名.pluck(第一引数, 第二引数, ・・・)
引数は第三引数、第四引数ともっととることができます。
その分値を(摘み)取ってくることが可能です。
今回の例でいくなら
Production.pluck(:name, :price)
のような形になります。
引数には自分がとってきたいカラム名が入ります。この時シンボルにするのを忘れないでください。
具体的にどんな挙動になるか見ていきましょう。
rails consoleで試してみます。
- 通常通りallで値を取得
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の値だけ取得
Production.pluck(:name)
実行結果です。
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値を取得
Production.pluck(:name, :price)
実行結果です。
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メソッドを使うと便利です。
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に送ることができそうです。
class ProductionsController < ApplicationController
def index
@productions_name_and_price = Production.pluck(:name, :price).to_h
end
end
controllerで定義したデータをハッシュにしてviewファイルに送り表示させます。
<div class="test">
<div class="test_name">
値段:<%= @productions_name_and_price[:"mac6世代"] %>円
</div>
</div>
無事にブラウザに表示されました。
pluckメソッドはmapメソッドと比べDBからデータの呼び出し方違うので、パフォーマンス的にも良いそうです。
気を付けること
pluckメソッドはクエリを直接トリガするので、その後ろに他のスコープをチェインすることはできないようです。
Production.pluck(:name).limit(1)
これはエラーになる。
おわりに
実際にはもっと簡単に表示させることができますが、今回はあえてpluckメソッドを用いて、viewに表示させてみました。どんな動きかを理解することってとても難しいです。これから実務の中でしっかり学んで一つ一つ理解していきたいと思います。
参考記事