環境 vagrant macOS
railsでredisのソート済みセット型を使ってブログ記事のpvランキングを作っています
pv数のカウントや(redis_access)pv数の表示(redis_page_view)はうまくいくのですが、
記事を削除した際にまとめてredisのデータも削除しようと、
・comment.rbにredis_deleteを記述し、
・destroyアクションで@comment.redis_deleteを記述しても
redisにデータがのこってしまいます。
ただ、redis-cliでzrem comments 46などを実行すると消えてくれます。
redis-cli
#奇数番が記事のid、偶数番号が記事のpv数 127.0.0.1:6379> zrevrangebyscore comments +inf -inf withscores 1) "6" 2) "92" 3) "46" 4) "3" 5) "48" 6) "2" 7) "49" 8) "1" 127.0.0.1:6379> zrem comments 46 (integer) 1 127.0.0.1:6379> zrevrangebyscore comments +inf -inf withscores 1) "6" 2) "92" 3) "48" #id46,pv数3の記事が消える 4) "2" 5) "49" 6) "1"
comment.rb
class Comment < ApplicationRecord validates :user_id, {presence: true} def redis_access REDIS.zincrby "comments", 1, self.id end def redis_page_view REDIS.zscore("comments", self.id).floor end def Comment.most_popular(limit: 3) most_popular_ids = REDIS.zrevrangebyscore "comments", "+inf", 0, limit: [0, 3] where(id: most_popular_ids).sort_by{ |comment| most_popular_ids.index(comment.id.to_s) } end def redis_delete REDIS.zrem "comments", params[:id] end end
comments.conroller.rb
class CommentsController < ApplicationController def test end def index @comments = Comment.all end def show @comment = Comment.find_by(id: params[:id]) @user = User.find_by(id: @comment.user_id) @comment.redis_access end before_action :authenticate_user, {only: [:new, :create, :edit, :update, :destroy]} def new end def create Comment.create(title: comment_params[:title], content: comment_params[:content],user_id: current_user.id) redirect_to("/comments/index") end def edit if Comment.find_by(id: params[:id]).user_id == current_user.id @comment = Comment.find_by(id: params[:id]) else flash[:notice] = "Not yours" redirect_to("/comments/index") end end def update if Comment.find_by(id: params[:id]).user_id == current_user.id @comment = Comment.find_by(id: params[:id]) @comment.title = comment_params[:title] @comment.content = comment_params[:content] @comment.save redirect_to("/comments/index") else flash[:notice] = "Not yours" redirect_to("/comments/index") end end def destroy if Comment.find_by(id: params[:id]).user_id == current_user.id @comment = Comment.find_by(id: params[:id]) @comment.redis_delete @comment.destroy redirect_to("/comments/index") else flash[:notice] = "Not yours" redirect_to("/comments/index") end end private def comment_params params.permit(:title,:content) end end
試したこと
rails,redisサーバーの再起動
redis_deleteを削除し、def redis_delete
REDIS.zrem "comments", params[:id]
endを追加
class Comment < ApplicationRecord validates :user_id, {presence: true} after_destroy do REDIS.zrem "comments", self.id end def redis_access REDIS.zincrby "comments", 1, self.id end def redis_page_view REDIS.zscore("comments", self.id).floor end def Comment.most_popular(limit: 3) most_popular_ids = REDIS.zrevrangebyscore "comments", "+inf", 0, limit: [0, 3] where(id: most_popular_ids).sort_by{ |comment| most_popular_ids.index(comment.id.to_s) } end end
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。