Wednesday, July 15, 2026 3:59:55 AM
> user_alias.rb
# frozen_string_literal: true

module ESM
  class UserAlias < ApplicationRecord
    # =============================================================================
    # INITIALIZE
    # =============================================================================

    # =============================================================================
    # DATA STRUCTURE
    # =============================================================================

    attribute :uuid, :uuid
    attribute :user_id, :integer
    attribute :community_id, :integer
    attribute :server_id, :integer
    attribute :value, :string
    attribute :created_at, :datetime
    attribute :updated_at, :datetime

    alias_attribute :public_id, :uuid

    # =============================================================================
    # ASSOCIATIONS
    # =============================================================================

    belongs_to :user
    belongs_to :community, optional: true
    belongs_to :server, optional: true

    # =============================================================================
    # VALIDATIONS
    # =============================================================================

    validates :value, uniqueness: {scope: [:user_id, :server_id]}
    validates :value, uniqueness: {scope: [:user_id, :community_id]}
    validates :value, length: {minimum: 1, maximum: 64}

    # =============================================================================
    # CALLBACKS
    # =============================================================================

    before_validation(on: :create) { self.uuid ||= SecureRandom.uuid }

    # =============================================================================
    # SCOPES
    # =============================================================================

    # =============================================================================
    # CLASS METHODS
    # =============================================================================

    def self.find_server_alias(value)
      eager_load(:server).where(value: value).where.not(server_id: nil).first
    end

    def self.find_community_alias(value)
      eager_load(:community).where(value: value).where.not(community_id: nil).first
    end

    def self.by_type
      eager_load(:community, :server)
        .each_with_object({community: [], server: []}) do |id_alias, hash|
          if id_alias.server
            hash[:server] << id_alias
          elsif id_alias.community
            hash[:community] << id_alias
          end
        end
    end

    # =============================================================================
    # INSTANCE METHODS
    # =============================================================================

    private

    def value_unique_within_scope
      return if value.blank?

      # Check for data integrity first
      if server_id.present? && community_id.present?
        errors.add(:base, "Alias cannot belong to both a server and community")
        return
      elsif server_id.blank? && community_id.blank?
        errors.add(:base, "Alias must belong to either a server or community")
        return
      end

      # Now do the actual uniqueness check
      query = self.class.where(
        user_id:,
        value:,
        server_id: server_id.presence,
        community_id: community_id.presence
      )

      query = query.where.not(id:) if persisted?
      errors.add(:value, "already exists") if query.exists?
    end
  end
end
All opinions represented herein are my own
- © 2024 - 2026 itsthedevman
- build 43aa0d7