Skip to content

Instantly share code, notes, and snippets.

@Kievbuy
Last active December 10, 2025 20:13
Show Gist options
  • Select an option

  • Save Kievbuy/4dcdc26e13d6e89b19201b2bb97c5a40 to your computer and use it in GitHub Desktop.

Select an option

Save Kievbuy/4dcdc26e13d6e89b19201b2bb97c5a40 to your computer and use it in GitHub Desktop.
refactoring
# frozen_string_literal: true
class Office
has_many :users
end
# frozen_string_literal: true
class OfficeUsersBalanceUpdater
def initialize(office_id, dates_that_change_balance)
@office = Office.find(office_id)
dates = dates_that_change_balance.with_indifferent_access # бідь які ключі приймаємо
@non_working_dates = dates[:non_working_dates]
@working_dates = dates[:working_dates]
end
def call
@office.users.active.includes(:vacations).find_each do |user| # find_each використовує батчі
update_balance(user, @non_working_dates)
update_balance(user, @working_dates, decrease: true)
end
end
private
def update_balance(user, dates, decrease: false)
return if dates.blank?
vacations = detect_vacations(user, dates)
return if vacations.blank?
dates_count = vacation_days_calculator(vacations, dates)
# ми не знаємо що в цих методах - якщо там ще додаткова бізнес логіка, то треба робити
# один за одним, якщо просто vacation_balance += n - то можна зробити bulk insert
if decrease
user.decrease_vacation_balance(dates_count)
else
user.increase_vacation_balance(dates_count)
end
end
def detect_vacations(user, dates)
user.vacations.not_declined.on_dates(dates.first, dates.last)
end
def vacation_days_calculator(vacations, dates)
dates_set = dates.to_set # по сету пошук швидше та ефективніше
vacations.inject(0) do |sum, v|
sum + (v.start_date.to_date..v.finish_date.to_date).count { |date| dates_set.include?(date.to_s) }
end
end
end
# frozen_string_literal: true
# Як викликається код
dates_that_change_balance = { non_working_dates: non_working_dates, working_dates: working_dates } # .stringify_keys більше не труба - ми додали with_indifferent_access в initialize
OfficeUsersBalanceUpdater.new(office.id, dates_that_change_balance).call
# frozen_string_literal: true
class User
belongs_to :office # була помилка -> 'offices' instead of 'office'
has_many :vacations
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment