Redis에서 순위 구현

16081 단어 RedisRails

처음에



Redis에서 순위를 구현해 보았습니다.



이 사이트를 참고로했습니다.
Rails에서 Redis를 사용하는 메모 랭킹 만들기
h tp //오. 이치키. jp/오br/307

설정



디자인은 bootstrap
더미 데이터 작성에 faker를 사용했습니다.

나중에 redis를 사용하기 때문에

gemfile에
gem 'redis'
gem 'bootstrap'
gem 'jquery-rails'
gem 'popper_js'
gem 'tether-rails'
gem 'faker'

이런 느낌으로 써서 bundle install했습니다.

user 모델을 만들었습니다.

bootstrap 설정 faker에서 더미 데이터 작성은 생략

구현



users_controller

users_controller.rb
class UsersController < ApplicationController
  def index
    @ranking_users_data = (REDIS.zrevrangebyscore "users", 10, 0, withscores: true)
  end

  def add_score
    user = User.find params[:id]
    REDIS.zincrby "users", 1, user.id
  end 
end

이런 식으로 했습니다.

REDIS에 관해서는

config/initializers 이하에 redis.rb를 작성해 내용에

redis.rb
REDIS = Redis.new(host: "localhost", port: 6379)

라고 쓰는 것으로 사용할 수 있습니다.
REDIS.zincrby "users", 1, user.id

같이 쓰고 있는 곳에서 스코어의 카운트를 하고 있습니다.

users가 점수를 계산하는 큰 정리의 이름으로 users가 아니어도 좋지만 이번에는 users라고 이름을 붙이고 있습니다.

그 뒤의 1이 추가하는 수입니다.

user.id마다 점수가 계산됩니다.

수집된 점수를 정렬된 상태로 출력하려면
REDIS.zrevrangebyscore "users", "+inf", 0, withscores: true

이 코드입니다.
점수가 +inf(최대?)에서 0까지 표시됩니다.

예를 들어 점수가 0에서 10까지 표시되고 싶다면
REDIS.zrevrangebyscore "users", 10, 0, withscores: true

어디까지나 스코어이므로 0부터 10번째를 표시하는 것은 아닙니다.

자신의 경우 이것뿐이라고 등록된 유저는 redis의 유저의 랭킹 안에 들어가지 않기 때문에
REDIS.zrevrangebyscore "users", 10, 0, withscores: true

이제 표시되지 않았습니다.

그래서 user가 작성되었을 때에 1점수를 두고 표시되도록(듯이) 했습니다.

models/user.rb

user.rb

class User < ApplicationRecord
    after_create{ REDIS.zincrby "users", 1, self.id}
end

routes는
Rails.application.routes.draw do
  get 'users/index'
  post 'users/add_score/:id', to: 'users#add_score'
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end

이런 식으로

보기는

index.html.erb
<br>
<br>
<br>
<br>
<br>
<div class="container">
    <table class="table table-dark">
        <thead>
            <tr>
            <th scope="col">Ranking</th>
            <th scope="col">Name</th>
            <th scope="col">Count</th>
            <th scope="col">Like Button</th>
            </tr>
        </thead>
        <tbody>
            <% @ranking_users_data.each_with_index do |rank_data,index| %>
                <tr>
                    <th scope="row"><%= index + 1 %></th>
                    <td><%= user_name(rank_data[0]) %></td>
                    <td class="count"><%= rank_data[1].to_i %></td>
                    <td>
                        <%= button_to "/users/add_score/#{rank_data[0]}", class: "like-btn", id: "addBtn",  remote: true do %>
                            <i class="fas fa-heart" style="font-size: 15px;" data-count="<%= index  %>"></i>
                        <% end %>

                    </td>
                </tr>
            <% end %>
        </tbody>
    </table>
</div>


<script>
var allBtn = document.getElementsByClassName('like-btn')
var allCount = document.getElementsByClassName('count')
var btnLength = allBtn.length 
var addLikeCount = function(i) {
    allCount[i].innerHTML = parseInt(allCount[i].innerHTML) + 1
}
for(var i = 0; i < btnLength; i++ ) {
    allBtn[i].addEventListener('click', function(a) {
        let dataCount = this.getElementsByClassName('fas')[0].dataset.count
        addLikeCount(dataCount);
    });
}

</script>

예제와 같이 자신은 자바 스크립트를 erb에 씁니다.

우선 외형은 이런 느낌이 된다고 생각합니다.



fontawesome을 사용하기 때문에

layouts의 head 안에
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css">

쓰기

assets/stylesheets/application.scss
@import '/*';
@import 'bootstrap';
@import 'tether';

body 
{
    background: #95a5a6;
}

.like-btn
{
    transition: all 0.2s;
    border: none !important;
}

.like-btn:hover
{
    background: rgb(224, 0, 37) !important;
    color: white !important;
    border: none !important;
}

이런 느낌으로 하고 있다고 외형은 같다고 생각합니다.

이제 클릭할 때마다 점수가 추가됩니다.

그건 그렇고



redis에 추가된 데이터를 보려면

rails c에서
REDIS.keys

그렇다면 등록 된 키가 나옵니다.
REDIS.zrevrangebyscore "users", "+inf", 0, withscores: true

라고 입력하면 user.id와 스코어가 2차 배열의 형태로 표시된다고 생각합니다.

좋은 웹페이지 즐겨찾기