4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ランキング機能の追加

Posted at

ランキング機能を追加する際に、製品毎にレビューが多い順に並べる場合、下記内容でデータを取り出すことができる。

ranking.rb
product_ids = Review.group(:product_id).order('count_product_id DESC').limit(5).count(:product_id).keys
    @ranking =  product_ids.map {|id| Product.find(id)}

reviewsカラム

id review product_id
1 text
2 test 1
3 text 1
4 text 3
5 text 3
6 text 2

product_id: 3>1>2の順にレビューが多い

productsカラム

id name
1 pen
2 glue
3 drill

①モデル名.group(:カラム名)
groupはモデルメソッドとして元からあるため、:product_idなどでグルーピングする。

②limit(表示したい要素数)
①のままだと最終的にproduct_idの種類全てを取得してしまうため、ランキングに載せたい数を制限する

③order('count_カラム名 DESC')
count_カラム名またはcount(カラム名)でカラムの種類ごとにカウントして
descで多い順に並べる。(少ない順ならasc)

ranking.rb
 pry(main)> id = Review.group(:product_id).order('count_product_id DESC').limit(5).count(:product_id).keys
=> [3, 1, 2]

pry(main)> id = Review.group(:product_id).limit(5).count(:product_id).keys
=> [1, 2, 3]
# order('count_product_id DESC')をつけないと、product_idの1から順に取り出すだけになってしまう

④count
product_id毎のデータ数を配列形式で並べたハッシュを返すことができる。
{2=>10, 1=>4, 3=>1}
見方としては{product_idが2個=>データ数10個,,,という表示方法になる。

⑤keys
順にハッシュのキーを配列として取り出す。

@ranking = map{|i| Product.find_by(product_id: i)}
map関数で配列の中を1つづつ取り出す。今product_idsの中にreviewが多い順にproduct_idが並んでいるため、find_byで各product_idのインスタンスを@rankingに代入する。

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?