51 lines
979 B
Ruby
51 lines
979 B
Ruby
class Ai::Quota < ApplicationRecord
|
|
class UsageExceedsQuotaError < StandardError; end
|
|
|
|
belongs_to :user
|
|
|
|
before_create -> { reset }
|
|
|
|
validates :limit, presence: true, numericality: { only_integer: true, greater_than_or_equal_to: 0 }
|
|
validates :used, presence: true, numericality: { only_integer: true, greater_than_or_equal_to: 0 }
|
|
|
|
def spend(cost)
|
|
cost = Money.wrap(cost)
|
|
|
|
transaction do
|
|
reset_if_due
|
|
increment!(:used, cost.in_microcents)
|
|
end
|
|
end
|
|
|
|
def ensure_not_depleted
|
|
reset_if_due
|
|
|
|
if depleted?
|
|
raise UsageExceedsQuotaError
|
|
end
|
|
end
|
|
|
|
private
|
|
def reset_if_due
|
|
reset if due_for_reset?
|
|
end
|
|
|
|
def reset
|
|
attributes = { used: 0, reset_at: 7.days.from_now }
|
|
|
|
if persisted?
|
|
update(**attributes)
|
|
else
|
|
assign_attributes(**attributes)
|
|
end
|
|
end
|
|
|
|
def due_for_reset?
|
|
reset_at.before?(Time.current)
|
|
end
|
|
|
|
def depleted?
|
|
used >= limit
|
|
end
|
|
end
|