Add a /user_actions page. This page shows you a global timeline of (almost) all activity on the site, including uploads, comments, votes, edits, forum posts, and so on. The main things it doesn't include are post edits, pool edits, and favorites (posts and pools live in a separate database, and favorites don't have the timestamps we need for ordering). This page is useful for moderation purposes because it lets you see a history of almost all of a user's activity on a single page. Currently this page is mod-only. In the future it will be open to all users, so you can view the history of your own site activity, or the activity of others.
94 lines
2.6 KiB
Ruby
94 lines
2.6 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class PostVote < ApplicationRecord
|
|
attr_accessor :updater
|
|
|
|
belongs_to :post
|
|
belongs_to :user
|
|
|
|
validates :score, inclusion: { in: [1, -1], message: "must be 1 or -1" }
|
|
|
|
before_save { post.lock! }
|
|
before_save :update_score_on_delete, if: -> { !new_record? && is_deleted_changed?(from: false, to: true) }
|
|
before_save :update_score_on_undelete, if: -> { !new_record? && is_deleted_changed?(from: true, to: false) }
|
|
before_save :create_mod_action_on_delete_or_undelete
|
|
before_create :update_score_on_create
|
|
before_create :remove_conflicting_votes
|
|
|
|
scope :positive, -> { where("post_votes.score > 0") }
|
|
scope :negative, -> { where("post_votes.score < 0") }
|
|
scope :public_votes, -> { active.positive.where.not(user: User.has_private_favorites) }
|
|
|
|
deletable
|
|
|
|
def self.visible(user)
|
|
if user.is_admin?
|
|
all
|
|
elsif user.is_anonymous?
|
|
public_votes
|
|
else
|
|
active.where(user: user).or(public_votes)
|
|
end
|
|
end
|
|
|
|
def self.search(params)
|
|
q = search_attributes(params, :id, :created_at, :updated_at, :score, :is_deleted, :user, :post)
|
|
|
|
q.apply_default_order(params)
|
|
end
|
|
|
|
def is_positive?
|
|
score > 0
|
|
end
|
|
|
|
def is_negative?
|
|
score < 0
|
|
end
|
|
|
|
def remove_conflicting_votes
|
|
PostVote.active.where.not(id: id).where(post: post, user: user).each do |vote|
|
|
vote.soft_delete!(updater: updater)
|
|
end
|
|
end
|
|
|
|
def validate_vote_is_unique
|
|
if !is_deleted? && PostVote.active.where.not(id: id).exists?(post: post, user: user)
|
|
errors.add(:user, "have already voted for this post")
|
|
end
|
|
end
|
|
|
|
def update_score_on_create
|
|
if is_positive?
|
|
Post.update_counters(post_id, { score: score, up_score: score })
|
|
else
|
|
Post.update_counters(post_id, { score: score, down_score: score })
|
|
end
|
|
end
|
|
|
|
def update_score_on_delete
|
|
if is_positive?
|
|
Post.update_counters(post_id, { score: -score, up_score: -score })
|
|
else
|
|
Post.update_counters(post_id, { score: -score, down_score: -score })
|
|
end
|
|
end
|
|
|
|
def update_score_on_undelete
|
|
update_score_on_create
|
|
end
|
|
|
|
def create_mod_action_on_delete_or_undelete
|
|
return if new_record? || updater.nil? || updater == user
|
|
|
|
if is_deleted_changed?(from: false, to: true)
|
|
ModAction.log("#{updater.name} deleted post vote ##{id} on post ##{post_id}", :post_vote_delete, updater)
|
|
elsif is_deleted_changed?(from: true, to: false)
|
|
ModAction.log("#{updater.name} undeleted post vote ##{id} on post ##{post_id}", :post_vote_undelete, updater)
|
|
end
|
|
end
|
|
|
|
def self.available_includes
|
|
[:user, :post]
|
|
end
|
|
end
|