# typed: true class User < ApplicationRecord extend T::Sig has_secure_password # Associations has_many :games, dependent: :destroy has_many :collections, dependent: :destroy has_many :items, dependent: :destroy has_many :api_tokens, dependent: :destroy has_many :igdb_match_suggestions, through: :games # Validations validates :email, presence: true, uniqueness: { case_sensitive: false }, format: { with: URI::MailTo::EMAIL_REGEXP } validates :username, presence: true, uniqueness: { case_sensitive: false }, length: { minimum: 3, maximum: 30 }, format: { with: /\A[a-zA-Z0-9_]+\z/, message: "only allows letters, numbers, and underscores" } validates :password, length: { minimum: 8 }, if: -> { password.present? } validates :theme, presence: true, inclusion: { in: %w[light dark midnight retro ocean] } # Callbacks before_save :downcase_email # Instance methods sig { returns(T::Boolean) } def generate_password_reset_token self.password_reset_token = SecureRandom.urlsafe_base64 self.password_reset_sent_at = Time.current save! end sig { returns(T::Boolean) } def password_reset_expired? password_reset_sent_at.nil? || password_reset_sent_at < 2.hours.ago end sig { returns(String) } def theme_class "theme-#{theme}" end private sig { void } def downcase_email self.email = email.downcase if email.present? end end