2
1

More than 1 year has passed since last update.

[Rails]ランキング機能、同率順位も考慮に入れ、順位ごとに色分けする

Last updated at Posted at 2022-08-13

この記事は投稿機能といいね機能が出来ている前提で進めています。
gurumeと書かれてるところは、僕用なので皆さんが作りたいプロダクト用に変えてください。あと、カラムも自分用に書き換えてください。
まず、コントローラーに以下のコードを書きます。

@rank_gurumes = Gurume.all.sort {|a,b| b.liked_users.count <=> a.liked_users.count}.first(3)

このコードはいいね数が多い順に並べるものになっています。first(3)はいいね数が多い3つを並べるという意味です。
次に、htmlに以下のコードをコピペしてください。

html
<div class="ranking">
    <div class="title_area">
      <div class="title">
        <h3>いいね数ランキング</h3>
      </div>
    </div>
    <div class="post">
      <% last_like = 0 %>
      <% j = 1 %>
        <% @rank_gurumes.each.with_index(1) do |t, i| %>
          <% if i == 1 %>
            <% last_like = t.likes.count %>
          <% end %>
          <% if t.likes.count != last_like %>
            <% j = i %>
            <% last_like = t.likes.count %>
          <% else %>
            <% last_like = t.likes.count %>
          <% end %>
          <% if j == 1 %>
            <div class="post1">
              <p><%= j %></p>
              <p>店の名前:<%= t.eatry_name %></p>
              <p>ジャンル:<%= t.genre %></p>
              <p>目的:<%= t.purpose %></p>
              <p>値段:<%= t.price %></p>
              <p>おいしさ:<%= t.delicious %></p>
              <p>アクセス:<%= t.access %></p>
              <p>その他:<%= t.others %></p>
              <p><%= image_tag t.image_url, size: "200x200" if t.image? %></p>
              <p>星評価:
              <div class="star">
                <% if t.star? %>
                  <% for i in 1..t.star do %><% end %>
                <% end %>
              </div>
              </p>
            </div>
          <% elsif j == 2 %>                
            <div class="post2">
              <p><%= j %></p>
              <p>店の名前:<%= t.eatry_name %></p>
              <p>ジャンル:<%= t.genre %></p>
              <p>目的:<%= t.purpose %></p>
              <p>値段:<%= t.price %></p>
              <p>おいしさ:<%= t.delicious %></p>
              <p>アクセス:<%= t.access %></p>
              <p>その他:<%= t.others %></p>
              <p><%= image_tag t.image_url, size: "200x200" if t.image? %></p>
              <p>星評価:
              <div class="star">
                <% if t.star? %>
                  <% for i in 1..t.star do %><% end %>
                <% end %>
              </div>
              </p>
            </div>
          <% else %>
            <div class="post3">
              <p><%= j %></p>
              <p>店の名前:<%= t.eatry_name %></p>
              <p>ジャンル:<%= t.genre %></p>
              <p>目的:<%= t.purpose %></p>
              <p>値段:<%= t.price %></p>
              <p>おいしさ:<%= t.delicious %></p>
              <p>アクセス:<%= t.access %></p>
              <p>その他:<%= t.others %></p>
              <p><%= image_tag t.image_url, size: "200x200" if t.image? %></p>
              <p>星評価:
              <div class="star">
                <% if t.star? %>
                  <% for i in 1..t.star do %><% end %>
                <% end %>
              </div>
              </p>
            </div>
          <% end %>
            
        <% end %>
    </div>

コードの解説を軽くします。まず同率順位の表し方についてです。こちらの記事を参考にさせていただきました。
ランキング機能の順位を同率表示する

html
<!--last_likeを定義して0を代入-->
<% last_like = 0 %>
<!--jを定義して1を代入-->
<% j = 1 %>
<% @rank_gurumes.each.with_index(1) do |t, i| %>
<!--1位のいいね数をlast_likeに保存-->
  <% if i == 1 %>
    <% last_like = t.likes.count %>
  <% end %>
<!--last_likeといいね数を比べて同じなら同じ順位、違うなら次の順位表示-->
  <% if t.likes.count != last_like %>
    <% j = i %>
    <% last_like = t.likes.count %>
  <% else %>
    <% last_like = t.likes.count %>
  <% end %>

!=は等しくないという意味です。

次にif文の解説です。

html
<!-- j == 1 の場合は以下の処理を-->
<% if j == 1 %>
    <div class="post1">
        <p><%= j %></p>
<!--省略-->
    </div>
<!-- j == 2 の場合は以下の処理を-->
<% elsif j == 2 %>                
    <div class="post2">
       <p><%= j %></p>
<!--省略-->   
    </div>
<!-- それ以外の条件の場合は以下の処理を-->
<% else %>
    <div class="post3">
      <p><%= j %></p>
<!--省略-->              
    </div>
<% end %>

次にscssに以下のコードをコピペします。このコードは1位の場合は金色を、2位の場合は銀色を3位の場合は銅色を設定しているだけです。

scss
.ranking {
        width: 100%;
        height: 100%;
        background-color: rgba(41, 210, 210, 0);
        margin: auto;
        padding: 46px 0px;
        .title_area{
            display: flex;
            justify-content: center;
            align-items: center;
            width: 100%;
            height: 60px;
            .title {
                width: 670px;
                height: 50px;
                background-color: rgba(91, 226, 226, 0);
                font-size: 35px;
                line-height: 40px;
                text-align: center;


            }
        }
        .post {
            display: flex;
            flex-direction: row;
            width: 100%;
            flex-wrap: wrap;
            align-items: flex-start;
            justify-content: center;
            .post1{
                width: 25%;
                margin: 3%;
                text-align: center;
                align-items: center;
                background-color: rgb(255, 204, 18);
            }
            .post2 {
                width: 25%;
                margin: 3%;
                text-align: center;
                align-items: center;
                background-color: darkgrey;
            }
            .post3 {
                width: 25%;
                margin: 3%;
                text-align: center;
                align-items: center;
                background-color: coral;
            }
        }
    }

そうするとこのような形になるはずです。
キータ1.png
キータ2.png

1枚目の写真は、同率順位はありませんが、順位ごとに色分けされていることが分かります。
2枚目の写真は、2位が同率順位になっており、その色が同じであることが分かります。

まとめ
いいねの数は同じなのに順位が違う、順位によって色分けをしたい方は是非参考にしてみて下さい。
今回、初めて記事を書いてみました。
間違いやその他意見ありましたらコメントいただけると幸いです。

2
1
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
2
1