discourse/app/models/topic_view_item.rb

53 lines
1.5 KiB
Ruby

require 'ipaddr'
# awkward TopicView is taken
class TopicViewItem < ActiveRecord::Base
self.table_name = 'topic_views'
belongs_to :user
validates_presence_of :topic_id, :ip_address, :viewed_at
def self.add(topic_id, ip, user_id=nil, at=nil, skip_redis=false)
# Only store a view once per day per thing per user per ip
redis_key = "view:#{topic_id}:#{Date.today.to_s}"
if user_id
redis_key << ":user-#{user_id}"
else
redis_key << ":ip-#{ip}"
end
if skip_redis || $redis.setnx(redis_key, "1")
skip_redis || $redis.expire(redis_key, 1.day.to_i)
TopicViewItem.transaction do
at ||= Date.today
# AR likes logging failures here, we don't need that
TopicViewItem.create!(topic_id: topic_id, ip_address: ip, viewed_at: at, user_id: user_id)
# Update the views count in the parent, if it exists.
Topic.where(id: topic_id).update_all 'views = views + 1'
end
end
rescue ActiveRecord::RecordNotUnique
# don't care, skip
end
end
# == Schema Information
#
# Table name: topic_views
#
# topic_id :integer not null
# viewed_at :date not null
# user_id :integer
# ip_address :inet not null
#
# Indexes
#
# index_topic_views_on_topic_id_and_viewed_at (topic_id,viewed_at)
# index_topic_views_on_viewed_at_and_topic_id (viewed_at,topic_id)
# ip_address_topic_id_topic_views (ip_address,topic_id) UNIQUE
# user_id_topic_id_topic_views (user_id,topic_id) UNIQUE
#