impressionist Gemでランキングを作る

みなさんこんにちは! Railsで僕がよく使うimpressionistというRailsのGemがあるのですが、それを用いてランキング機能を作りたい!と思ったので共有します。 一参考になればいいなぁと思います。

ランキングのコード

ひとまずコードです。

# return [ #, #, ....]
def daily_article_ranking
  ids = Impression.where("created_at >= ?", Time.now.yesterday).where("created_at <= ?", Time.now).group(:impressionable_id).order('count_all desc').limit(10).count.keys
  Article.where(:id => ids).order("field(id, #{ids.join(',')})")
end

設定としてはArticle modelが存在していて、そのPVを取得している、という状況を考えています。 また、現在から考えて1日の間のrankingなのでもし◯日のランキングを作る、とかそういう場合は適宜変えていただければ、と。 これを適切なhelperに入れてもらえれば便利かと思います。

以下解説です。 まずはimpressionテーブルから必要なデータを抜き出し、グループ化してカウントし、Article idを10件ほど取得します。 そのときに参考にさせていただいた記事は以下になります。 Rails で group by して count を取りたい時のイディオム

そしてそのidsを元にidsの配列に入っているid順にArticle modelからデータを引っ張ってきます。 そのときに参考にさせていただいたのは以下の記事(英語) Finding an array of ids while keeping the order with Rails 今回例としてあげたコードはMySQLをデータベースとして考えているのですが、こちらの記事内でMySQL以外のデータベースの場合、という風にコードが示してあるのでそれを参考に書き換えていただければ動くのではないかと思います。

こんな感じでランキングをイメージしたデータを返すことが出来るようになりました! これをもとにviewを調整していただければランキングの完成です!!

最後に

Impressionist Gem便利ですね。