Files
danbooru/app/models/post_vote.rb
evazion ee638f976f Add /user_actions page.
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.
2022-09-16 05:39:25 -05:00

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