Files
2025-12-12 09:59:42 +01:00

37 lines
852 B
Ruby

class Account::JoinCode < ApplicationRecord
CODE_LENGTH = 12
USAGE_LIMIT_MAX = 10_000_000_000
belongs_to :account
validates :usage_limit, numericality: { less_than_or_equal_to: USAGE_LIMIT_MAX, message: "cannot be larger than the population of the planet" }
scope :active, -> { where("usage_count < usage_limit") }
before_create :generate_code, if: -> { code.blank? }
def redeem_if(&block)
with_lock do
increment!(:usage_count) if active? && block.call(account)
end
end
def active?
usage_count < usage_limit
end
def reset
generate_code
self.usage_count = 0
save!
end
private
def generate_code
self.code = loop do
candidate = SecureRandom.base58(CODE_LENGTH).scan(/.{4}/).join("-")
break candidate unless self.class.exists?(code: candidate)
end
end
end