조회수 구현 (impressionist)
impressionist
원래 처음에는 Gem의 힘을 빌리지 않고 조회수를 구현하려고 했는데 막 DB에 새로운 컬럼을 추가해서 순수적으로해보려고 해보는데 잘 안되네요.. 거의 막판에 포기할 무렵...... 조회수 관련해서 전문적으로 기능을 담당하는 Gem 있다는걸 알게됩니다....
게다가 마침 IP대조까지 해서 조회수 증감 판단도 한다네요.... 이번엔 이 기능에 대해서 소개하고자 합니다.
조회수 기능 (IP Check 포함)
- Gemfile에 다음 내용을 추가합니다.
gem 'impressionist'
그리고 명령어 입력창(터미널)에 다음 명령어를 칩니다.
bundle install
- bundle install 작업이 끝나면, 명령어 입력창(터미널)에 다음 명령어를 칩니다.
rails g impressionist
그러면 /db/migrate에 impressions_table.rb라는 새로운 파일을 보게될 수 있습니다.
그런데 여기서 어느정도 선행이 되신분은 바로 migrate를 시도하실텐데, 시도를 하게 되면 에러가 날 것입니다.
migrate를 하시기전, /db/migrate/impressions_table.rb 로 가시고, 다음 내용을 수정합니다.
# Before
#class CreateImpressionsTable < ActiveRecord::Migration
#... (이하 내용생략) ...
# After
class CreateImpressionsTable < ActiveRecord::Migration[5.1]
... (이하 내용생략) ...
수정 후, 명령어 입력창(터미널)에 다음 명령어를 쳐서 migrate를 하시면 잘 작동이 됩니다.
rake db:migrate
- [필자 작성 기준 설명] /app/models/post.rb(게시판 관련 model파일)에서 다음 내용을 추가합니다.
class Post < ApplicationRecord
...
has_many :impressions, :as=>:impressionable
def impression_count
impressions.size
end
def unique_impression_count
# impressions.group(:ip_address).size gives => {'127.0.0.1'=>9, '0.0.0.0'=>1}
# so getting keys from the hash and calculating the number of keys
impressions.group(:ip_address).size.keys.length #TESTED
end
...
end
- [필자 작성 기준 설명] /app/controllers/posts_controller.rb(게시판 관련 controller파일)에서 다음 내용을 추가합니다.
class PostsController < ApplicationController
...
before_action :log_impression, :only=> [:show]
def log_impression
@hit_post = Post.find(params[:id])
# this assumes you have a current_user method in your authentication system
@hit_post.impressions.create(ip_address: request.remote_ip,user_id:current_user.id)
end
...
end
- 조회수가 노출되길 원하는 view에 가서 다음 변수를 추가함으로서, '조회수 출력' 변수를 추가합니다.
<%= "#{@post변수.unique_impression_count}" %>
저는 예시로, 게시판 목록에 조회수가 나타나게 표현해보겠습니다.
app/views/posts/list.html.erb (8번째 줄)
<% @allpost.each do |p| %>
<table border="0" width="100%">
<tr bgcolor="white" onMouseOver="this.style.backgroundColor='#ECECEC'" onMouseOut="this.style.backgroundColor='#FFFFFF'">
<td width="4%"><div class="board_num"><%= p.id %></div></td>
<td width="20%" align="left" style="border-bottom: 1px dashed gray;"><i class="fa fa-user-o" aria-hidden="true"></i> <%= p.user.nickname %></td>
<td width="56%" align="left" style="border-bottom: 1px dashed gray;"><div class="board_title"><a style="margin-left: 20px;" href="/posts/show/<%= p.id %>"><%= p.title %></a></div></td>
<td width="5%" align="left" style="border-bottom: 1px dashed gray;"><i class="fa fa-clock-o" aria-hidden="true"></i> <%= "#{time_ago_in_words(p.created_at)} 전" %></td>
<td width="5%" align="left" style="border-bottom: 1px dashed gray;"> <%= "#{p.unique_impression_count} views" %></td>
<td bgcolor="#FEFFDC" width="5%" align="center" style="border-bottom: 1px dashed gray;"><i class="fa fa-thumbs-o-up" aria-hidden="true"></i> <%= p.likes.size %></td>
</tr>
</table>
<% end %>
참고
Git - impressionist : https://github.com/charlotte-ruby/impressionist
Stackoverflow : https://stackoverflow.com/questions/4815713/simple-hit-counter-for-page-views-in-rails
Stackoverflow(IP체크 X) : https://stackoverflow.com/questions/23174338/counting-page-views-using-impressionist-gem-ruby-on-rails