はじめに
ランキング順で表示する際の考え方についてつまづいてしまったので、
考え方を残しておきます。
前提
投稿、いいね、タグ それぞれの機能は作成済みとします。
# 方法
投稿に紐づくいいね順
まず、posts テーブルと likesテーブルには、以下のようなデータが入っているとします。
まずやることは、2つのテーブルを合体させます。
likesテーブルのpost_idとpostsテーブルのidは、同じになるはずです。
"postに紐づくいいねを、多い順に並べる"
↓
"likesテーブルのpost_idの数を集計し、多い順に並べる"
と言うことになります。
likesテーブルにはそもそもいいねをもらったpostのidが存在します。
likesのidは、いいねするたびに増えていきます。
post_idはlikesテーブルの中では重複するものであり、ひとつの投稿に着目すると、
その投稿がいいねされるたびにlikesテーブルの特定のpost_idは増えていきます。
だから、likesテーブルに存在するpost_idを数えれば、どのpostがどのくらいいいねをもらっているかがわかり、比較できるのです。
上記記事を参考に、
@posts = Post.find(Like.group(:post_id).order('count(post_id) desc').limit(3).pluck(:post_id))
と書くことができます。
#likeモデルのpost_idカラムを指定してまとめる
Post.find(Like.group(:post_id)
#post_idの多い順に並べる
.order('count(post_id) desc')
#並び替えたものの上位3つのpost_idを抽出する
.limit(3).pluck(:post_id))
タグに紐づく投稿順
こちらも、いいねと同じ考え方でいけます。
まず、postとtagを結ぶpost_tagモデルが存在します。
今回行いたいのは、postに紐づくタグの中で、より多くのpostを保有するタグを順番に並べたいです。
簡単に言うと、よく使われるタグを順番に並べたいです。
post_tagテーブルと、tagテーブルは以下の通りです。
これを合体します。
今回は、post_tagテーブルのidと、tagsテーブルのtag_idが一致するはずです。
tagに紐づいているpostの数を比較したいので、
今回はpost_tagsテーブルの、tag_idの数を集計して、多い順に並べれば良いです。
postとtagのセットの情報が、post_tagsテーブルに保管されるので、
post_tagsテーブルのtag_idで頻出のタグは、より多くのpostに紐づいていると言うことです。
実際には、
@tags = Tag.find(PostTag.group(:tag_id).order('count(tag_id) desc').limit(10).pluck(:tag_id))
と書くことができます。
#Postモデルのtag_idカラムを指定してまとめる
Tag.find(PostTag.group(:tag_id)
#tag_idを数え数の多い順に並び替える
.order('count(tag_id) desc')
#並び替えたものの上位10個のtag_idを抽出する
.limit(10).pluck(:tag_id))
いいねもタグも、最終的に複数のidをpluckで取り出しているので、
@posts, @tagsなどのインスタンス変数に格納し、ビューでeach文を使用してデータを一覧表示すればOKです。
groupメソッドについても確認する必要がありました。
しっかり理解ができれば、色々簡単に応用ができます。