ここまでランキング機能に関する記事を2記事書いてきました
[Rails]いろんなランキング表示(いいね、コメント、投稿数)
[Rails]月間、週間、日別でランキング機能を実装(Time.current)
上記の記事でも順位を表示する方法を紹介しているのですが、同率の場合でも順位が1位、2位となっていました。
たとえば、いいね数のランキングでいいね数が5のAさん、Bさん、いいね数が3のCさんがいたとします。
そのときの順位は1位Aさん、2位Bさん、3位Cさんとなってしまいます。
それを今回、1位Aさん、1位Bさん、3位Cさんと同率の場合は順位を同じにしていきます。
#開発環境
ruby 2.6.3
Rails 5.2.6
#前提
- 投稿サイトを想定
- ランキングの順位に応じて1位、2位などの順位を表示(同率の場合は同率で順位を表示)
- ranksコントローラーのrankアクションに処理を記述
- rank.html.erbでビューを表示
モデル名、変数名等は適宜、ご自身の開発環境に変換してお考えください。
user ユーザー
post 投稿
like いいね
comment コメント
#まず結論から
まず、結論のコードを見せてそのあとに解説していきます。
<!--同率順位表示-->
<% last_like = 0 %>
<% j = 1 %>
<% @post_like_ranks.each.with_index(1) do |rank, i| %>
<!--最初の値をlast_likeに保存-->
<% if i == 1 %>
<% last_like = rank.likes.count %>
<% end %>
<!--last_likeといいね数比べて同じなら同じ順位、違うなら次の順位表示-->
<% if rank.likes.count != last_like %>
<% j = i %>
第<%= j %>位
<p><%= rank.likes.count %>いいね</p>
<% last_like = rank.likes.count %>
<% else %>
<% last_like = rank.likes.count %>
第<%= j %>位
<p><%= rank.likes.count %>いいね</p>
<% end %>
<% end %>
長々とコード書いてるので解説していきます。
#解説
基本的な考え方としては、last_likeという変数にいいねのカウント数を入れていき、last_likeといいねのカウント数を比べて、同じなら同じ順位を表示、違うなら次の順位を表示していく流れです。
なので処理としてはそんなに難しいことはせずに、if文で条件分岐しているだけなので安心してください。
では、コードを細かくみていきましょう!
<!--last_likeを定義して0を代入-->
<% last_like = 0 %>
<!--jを定義して1を代入-->
<% j = 1 %>
<!--いいねの多い順に並べたものを配列でまわす-->
<% @post_like_ranks.each.with_index(1) do |rank, i| %>
:
<% end %>
<!--順位が1位のときlast_likeに値は入っていないため、1位のいいねのカウント数を代入-->
<% if i == 1 %>
<% last_like = rank.likes.count %>
<% end %>
<!--rank.likes.countとlast_likeを比べて条件分岐-->
<!--値が一致しないとき-->
<% if rank.likes.count != last_like %>
<!--値が一致しないということは次の順位を表示したいので-->
<!--j に i を代入して表示-->
<% j = i %>
第<%= j %>位
<p><%= rank.likes.count %>いいね</p>
<!--値が一致していなのでlast_likeの値を更新-->
<% last_like = rank.likes.count %>
<% else %>
<!--last_likeといいねのカウント数が同じとき-->
<!--値は同じですが今後も使うので、代入しておく-->
<% last_like = rank.likes.count %>
<!--jには前の順位と同じ値が入っているので、更新せずそのまま表示-->
第<%= j %>位
<p><%= rank.likes.count %>いいね</p>
<% end %>
#最後に
ひとつずつ見ていくとそこまで難しい記述ではなかったとは思うので、理解できていると思います。
今後も使う機会が多そうな処理なので、しっかりと理解してまた色んな場面で再現できるようにしておきましょう。