コントローラーからデータをいかに処理してまとめられる
備忘録を書きます。
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
