先日、基本的なランキング機能の表示方法を記事にしたので、今回はランキング機能の応用編ということで、月間、週間などの期間を指定してのランキング機能を実装していきます。
先日書いた記事はこちら
[Rails]いろんなランキング表示(いいね、コメント、投稿数)
同率順位表示する記事もあげました
ランキング機能の順位を同率表示する
#開発環境
ruby 2.6.3
Rails 5.2.6
#前提
- 投稿サイトを想定
- ランキングの順位に応じて1位、2位などの順位を表示
- ranksコントローラーのrankアクションに処理を記述
- rank.html.erbでビューを表示
モデル名、変数名等は適宜、ご自身の開発環境に変換してお考えください。
user ユーザー
post 投稿
like いいね
comment コメント
#ビュー
postとuserで渡す変数や表示させたいカラムが違うだけなので、先にやっつけておきます。
postのランキングを例にします。
1位、2位と順位を表示したいので、with_indexを使います。
<!--配列の1つ目から順に1位、2位と表示される-->
<% post_ranks.each.with_index(1) do |post, i| %>
第<%= i %>位
:
<!--表示したいカラムをご自由に-->
:
<% end %>
こうするだけで、順位が表示されるようになります。
#これだけ押さえておけばいい
実際のランキング表示方法の前に、これだけ押さえておけばいいポイントを説明します。
ずばり、Time.current
です!
Time.current
さえ理解できたら期間指定系のランキング機能は9割実装できたも同然です!
Time.currentとはRails独自のメソッドです。
Time.currentを使うことで、今の日時が取得できます。
ではコンソールで試してみましょう!
# rails cを実行
$rails c
# Time.currentを実行すると現在の日時が表示される
001 > Time.current
=> Wed, 07 Jul 2021 01:25:38 UTC +00:00
これでTime.currentで現在の日時が取得できることがわかったはず。
とても便利なメソッドです。
このTime.currentを軸に今月、今週、今日とデータを取得していきます。
方法は簡単でTime.current.all_week
とすると現在の日時を含む全ての週、つまり今週という期間を指定できます。
ではコンソールで試していきます。
# 今月を表示
002 > Time.current.all_month
# すると今が2021年7月なので2021/7/1~2021/7/31までが指定される
=> Thu, 01 Jul 2021 00:00:00 UTC +00:00..Sat, 31 Jul 2021 23:59:59 UTC +00:00
# 今週を表示
003 > Time.current.all_week
=> Mon, 05 Jul 2021 00:00:00 UTC +00:00..Sun, 11 Jul 2021 23:59:59 UTC +00:00
# 今日を表示
004 > Time.current.all_day
=> Wed, 07 Jul 2021 00:00:00 UTC +00:00..Wed, 07 Jul 2021 23:59:59 UTC +00:00
しっかりと対象の期間が取得できています。
たとえば、Time.current.all_weekではなく、'指定の日時'.all_week
で指定の日時を含む週を取得できたり、Time.current.ago(2.years)
で今日の2年前を取得できたりもするので、色々覚えておくと便利だと思います。
時刻や日付を扱うメソッドの基本情報まとめ【Ruby】【Rails】
では以上を踏まえて実際にコードを書いていきます。
#月間ランキング
月間ランキングでは、ユーザーの投稿数のランキングを例にしていきます。
def rank
# 月間ランキング
@month_user_post_ranks = User.where(id: Post.group(:user_id).where(created_at: Time.current.all_month).order('count(user_id) desc').pluck(:user_id))
end
解説します。
#Postモデルのuser_idが同じのまとめる
Post.group(:user_id)
#投稿が作られた日が今月のデータのみ抽出
where(created_at: Time.current.all_month)
#user_idが多い順に並べる
order('count(user_id) desc')
#user_idで取り出す
pluck(:user_id)
#Userモデルのidが一致するデータを取得する
User.where(id: )
これで、今月のユーザーの投稿数ランキングができました。
#週間ランキング
週間ランキングでは、投稿のいいね数ランキングを例にしていきます。
def rank
# 週間ランキング
@week_post_like_ranks = Post.find(Like.group(:post_id).where(created_at: Time.current.all_week).order('count(post_id) desc').pluck(:post_id))
end
解説します。
# Postモデルから()内のデータを探してくる
Post.find()
# 次にLikeモデルのpost_idが同じものをまとめる
Like.group(:post_id)
#投稿が作られた日が今週のデータのみ抽出
where(created_at: Time.current.all_week)
# まとめたものをpost_idの多い順に並び替える
order('count(post_id) desc')
# そのままだとLikeモデルで取り出してしまうので、post_idで値を取りだす
pluck(:post_id)
これで今週の投稿のいいね数ランキングができました。
#日別ランキング
日別ランキングでは、投稿のコメント数ランキングを例にしていきます。
def rank
# 日別ランキング
@today_post_comment_ranks = Post.find(Comment.group(:post_id).where(created_at: Time.current.all_day).order('count(post_id) desc').pluck(:post_id))
end
いいね数ランキングと考え方は同じで、いいねをコメントに、all_weekをall_dayに変更しただけなので、詳しい説明は割愛させていただきます。
#最後に
今回はTime.currentメソッドを使って期間を指定してランキング機能を実装しました。
時間を扱えるメソッドはTime.current以外にもたくさんあって、メソッドの使い分けをしていくようです。
ぼくもまだまだ知らないメソッドだらけなので、日々勉強していきます。
最後まで見て頂きありがとうございました。