コントローラーからデータをいかに処理してまとめられる
備忘録を書きます。
groupメソッド
groupメソッドはテーブルのレコードを指定したカラムでまとめることができます。
モデル.group(カラム名)
# 例
Rei.group(:product_id)
# これでproduct_idの21,22,23,などにまとめられ格product_idの先頭が出力されます。
countメソッド
countメソッドは配列などの要素数を返すメソッドです。
Rei.group(:product_id).count
=> {21=>2, 22=>1, 23=>4}
order('count_カラム名').count(カラム名)
countメソッドの引数にカラム名を指定することができます。
するとorderメソッドでcount_カラム名でのソートが可能となります。
これはそのカラムを持つレコードの数でソートするという意味です。
ここでlimitの注意点です
count(:product_id)の時点ではハッシュになっているため
その後に付け加えるとハッシュに対してlimitメソッドを実行することになりエラーが起こります。
そのため、その直前に付け加え、下記のようにします。
order('count_カラム名').count(カラム名
# 例
Rei.group(:product_id).order('count_product_id DESC').limit(5).count(:product_id)
=> {23=>4, 21=>2, 22=>1}
keysメソッド
ハッシュはkeysというメソッドを持っています。
これはハッシュのキーだけを取り出して配列として返すメソッドです。
# 例
Rei.group(:product_id).order('count_product_id DESC').limit(5).count(:product_id).keys
=> [23, 21, 22]
mapメソッド
whereで値を配列にした場合、並びがid順になってしまうので。
この問題を解決するためにmapメソッドを使用します。
mapメソッドは配列オブジェクトのインスタンスメソッドです。
mapメソッドは配列の中身を1つずつ取り出してブロックという構文を繰り返し実行します。
そして、ブロックの返り値を集めた新しい配列を作成します。
配列オブジェクト.map {|ele| ブロックの処理}
# eleには配列の要素が1つずつ代入される
# ブロックの処理は配列の要素の数だけ繰り返し実行される
# 例
class RankingController < ApplicationController
def ranking
product_ids = Rei.group(:product_id).order('count_product_id DESC').limit(5).count(:product_id).keys
# これでproduct_idの多い順に並ばれました。
@ranking = product_ids.map { |id| Product.find(id) }
#Prodict_idsを順番に実行してproductテーブルからインスタンスを持ってきます。
end
end