Do not touch statuses_count on accounts table when mass-destroying statuses to reduce load when removing accounts, same for reblogs_count and favourites_count Do not count statuses with direct visibility in statuses_count Fix #828
		
			
				
	
	
		
			51 lines
		
	
	
	
		
			1.5 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
			
		
		
	
	
			51 lines
		
	
	
	
		
			1.5 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
# frozen_string_literal: true
 | 
						|
# == Schema Information
 | 
						|
#
 | 
						|
# Table name: favourites
 | 
						|
#
 | 
						|
#  id         :bigint(8)        not null, primary key
 | 
						|
#  created_at :datetime         not null
 | 
						|
#  updated_at :datetime         not null
 | 
						|
#  account_id :bigint(8)        not null
 | 
						|
#  status_id  :bigint(8)        not null
 | 
						|
#
 | 
						|
 | 
						|
class Favourite < ApplicationRecord
 | 
						|
  include Paginable
 | 
						|
 | 
						|
  update_index('statuses#status', :status) if Chewy.enabled?
 | 
						|
 | 
						|
  belongs_to :account, inverse_of: :favourites
 | 
						|
  belongs_to :status,  inverse_of: :favourites
 | 
						|
 | 
						|
  has_one :notification, as: :activity, dependent: :destroy
 | 
						|
 | 
						|
  validates :status_id, uniqueness: { scope: :account_id }
 | 
						|
 | 
						|
  before_validation do
 | 
						|
    self.status = status.reblog if status&.reblog?
 | 
						|
  end
 | 
						|
 | 
						|
  after_create :increment_cache_counters
 | 
						|
  after_destroy :decrement_cache_counters
 | 
						|
 | 
						|
  private
 | 
						|
 | 
						|
  def increment_cache_counters
 | 
						|
    if association(:status).loaded?
 | 
						|
      status.update_attribute(:favourites_count, status.favourites_count + 1)
 | 
						|
    else
 | 
						|
      Status.where(id: status_id).update_all('favourites_count = COALESCE(favourites_count, 0) + 1')
 | 
						|
    end
 | 
						|
  end
 | 
						|
 | 
						|
  def decrement_cache_counters
 | 
						|
    return if association(:status).loaded? && (status.marked_for_destruction? || status.marked_for_mass_destruction?)
 | 
						|
 | 
						|
    if association(:status).loaded?
 | 
						|
      status.update_attribute(:favourites_count, [status.favourites_count - 1, 0].max)
 | 
						|
    else
 | 
						|
      Status.where(id: status_id).update_all('favourites_count = GREATEST(COALESCE(favourites_count, 0) - 1, 0)')
 | 
						|
    end
 | 
						|
  end
 | 
						|
end
 |