class Post < ApplicationRecord
# View counter - increments without hitting the database
kredis_counter :view_count, expires_in: 1.day
# Recent viewers list - stores last 10 viewer IDs
kredis_unique_list :recent_viewers, limit: 10
# Flag for featured status
kredis_flag :featured
# Hash for cached statistics
kredis_hash :statistics
def increment_views!(user_id)
view_count.increment
recent_viewers.prepend(user_id)
# Update database counter periodically
if view_count.value % 10 == 0
update_column(:views, views + 10)
end
end
def viewer_count
recent_viewers.elements.size
end
def stats
statistics.entries.presence || compute_and_cache_stats
end
private
def compute_and_cache_stats
stats = {
'likes' => likes.count,
'comments' => comments.count,
'shares' => shares.count
}
statistics.update(stats)
stats
end
end
module Api
module V1
class PostsController < ApplicationController
def show
post = Post.find(params[:id])
# Increment view count
post.increment_views!(current_user&.id || "anon_#{request.remote_ip}")
render json: post.as_json.merge(
view_count: post.view_count.value,
viewer_count: post.viewer_count,
statistics: post.stats
)
end
end
end
end
Kredis provides typed Redis structures as Active Model attributes, simplifying common patterns like counters, flags, and lists. Instead of raw Redis commands, I define kredis accessors on models that handle serialization automatically. Counters track metrics like view counts, lists manage ordered collections, and flags store boolean states. Kredis uses connection pooling and handles expiration seamlessly. For real-time features, I combine Kredis with Action Cable—store online users in a Redis set, broadcast presence updates. The library integrates with Rails' encrypted credentials for sensitive data. This abstraction makes Redis feel like native Rails, improving developer productivity while maintaining performance.