106 lines
2.9 KiB
Ruby
106 lines
2.9 KiB
Ruby
|
|
class Kudo < ApplicationRecord
|
||
|
|
include Responder
|
||
|
|
|
||
|
|
VALID_COMMENTABLE_TYPES = %w[Work].freeze
|
||
|
|
|
||
|
|
belongs_to :user
|
||
|
|
belongs_to :commentable, polymorphic: true
|
||
|
|
|
||
|
|
validates :commentable_type, inclusion: { in: VALID_COMMENTABLE_TYPES }
|
||
|
|
validates :commentable,
|
||
|
|
presence: true,
|
||
|
|
if: proc { |c| VALID_COMMENTABLE_TYPES.include?(c.commentable_type) }
|
||
|
|
|
||
|
|
validates :user, not_blocked: { by: :commentable, on: :create }
|
||
|
|
|
||
|
|
validate :cannot_be_author, on: :create
|
||
|
|
def cannot_be_author
|
||
|
|
return unless user&.is_author_of?(commentable)
|
||
|
|
|
||
|
|
errors.add(:commentable, :author_on_own_work)
|
||
|
|
end
|
||
|
|
|
||
|
|
validate :guest_cannot_kudos_restricted_work, on: :create
|
||
|
|
def guest_cannot_kudos_restricted_work
|
||
|
|
return unless user.blank? && commentable.is_a?(Work) && commentable.restricted?
|
||
|
|
|
||
|
|
errors.add(:commentable, :guest_on_restricted)
|
||
|
|
end
|
||
|
|
|
||
|
|
validate :cannot_be_suspended, on: :create
|
||
|
|
def cannot_be_suspended
|
||
|
|
return unless user&.banned || user&.suspended
|
||
|
|
|
||
|
|
if user.banned
|
||
|
|
errors.add(:commentable, :user_is_banned)
|
||
|
|
else
|
||
|
|
errors.add(:commentable, :user_is_suspended)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
validates :ip_address,
|
||
|
|
uniqueness: { scope: [:commentable_id, :commentable_type] },
|
||
|
|
if: proc { |kudo| kudo.ip_address.present? }
|
||
|
|
|
||
|
|
validates :user_id,
|
||
|
|
uniqueness: { scope: [:commentable_id, :commentable_type] },
|
||
|
|
if: proc { |kudo| kudo.user.present? }
|
||
|
|
|
||
|
|
validate :cannot_be_official_user, on: :create
|
||
|
|
def cannot_be_official_user
|
||
|
|
return unless user&.official
|
||
|
|
|
||
|
|
errors.add(:user, :official)
|
||
|
|
end
|
||
|
|
|
||
|
|
validate :cannot_be_archivist_account, on: :create
|
||
|
|
def cannot_be_archivist_account
|
||
|
|
return unless user&.archivist
|
||
|
|
|
||
|
|
errors.add(:user, :archivist)
|
||
|
|
end
|
||
|
|
|
||
|
|
scope :with_user, -> { where("user_id IS NOT NULL") }
|
||
|
|
scope :by_guest, -> { where("user_id IS NULL") }
|
||
|
|
|
||
|
|
after_destroy :update_work_stats
|
||
|
|
after_create :after_create, :update_work_stats
|
||
|
|
def after_create
|
||
|
|
users = self.commentable.pseuds.map(&:user).uniq
|
||
|
|
|
||
|
|
users.each do |user|
|
||
|
|
if notify_user_by_email?(user)
|
||
|
|
RedisMailQueue.queue_kudo(user, self)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
after_save :expire_caches
|
||
|
|
def expire_caches
|
||
|
|
if commentable_type == "Work"
|
||
|
|
# Expire the work's cached total kudos count.
|
||
|
|
Rails.cache.delete("works/#{commentable_id}/kudos_count-v2")
|
||
|
|
# If it's a guest kudo, also expire the work's cached guest kudos count.
|
||
|
|
Rails.cache.delete("works/#{commentable_id}/guest_kudos_count-v2") if user_id.nil?
|
||
|
|
end
|
||
|
|
|
||
|
|
# Expire the cached kudos section under the work.
|
||
|
|
ActionController::Base.new.expire_fragment("#{commentable.cache_key}/kudos-v4")
|
||
|
|
end
|
||
|
|
|
||
|
|
def notify_user_by_email?(user)
|
||
|
|
user.nil? ? false : ( user.is_a?(Admin) ? true :
|
||
|
|
!(user == User.orphan_account || user.preference.kudos_emails_off?) )
|
||
|
|
end
|
||
|
|
|
||
|
|
# Return either the name of the kudo-giver or "guest".
|
||
|
|
# Used in kudo notifications.
|
||
|
|
def name
|
||
|
|
if self.user
|
||
|
|
user.login
|
||
|
|
else
|
||
|
|
"guest"
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|