You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: tenant_quota.rb
    path of file: ./repos/manageiq/app/models
    
    the code of the file until where you have to start completion: class TenantQuota < ApplicationRecord
  belongs_to :tenant

  QUOTA_BASE = {
    :cpu_allocated       => {
      :unit          => :fixnum,
      :format        => :general_number_precision_0,
      :text_modifier => N_("Count").freeze
    },
    :mem_allocated       => {
      :unit          => :bytes,
      :format        => :gigabytes_human,
      :text_modifier => N_("GB").freeze
    },
    :storage_allocated   => {
      :unit          => :bytes,
      :format        => :gigabytes_human,
      :text_modifier => N_("GB").freeze
    },
    :vms_allocated       => {
      :unit          => :fixnum,
      :format        => :general_number_precision_0,
      :text_modifier => N_("Count").freeze
    },
    :templates_allocated => {
      :unit          => :fixnum,
      :format        => :general_number_precision_0,
      :text_modifier => N_("Count").freeze
    }
  }

  DEFAULT_TEXT_FOR_ZERO_VALUES = {
    :total     => "Not defined".freeze,
    :available => "Not applicable".freeze
  }

  NAMES = QUOTA_BASE.keys.map(&:
    
  def allocated
    tenant.children.includes(:tenant_quotas).map do |c|
      cq = c.tenant_quotas.send(name).take
      cq.value if cq
    end.compact.sum
  end

  def available
    value - tenant.children.includes(:tenant_quotas).map do |c|
      cq = c.tenant_quotas.send(name).take
      cq.value if cq
    end.compact.sum - used
  end

  def used
    method = "#{name.split("_").first}_used"
    @used ||= send(method)
  end

  def cpu_used
    tenant.allocated_vcpu
  end

  def mem_used
    tenant.allocated_memory
  end

  def storage_used
    tenant.allocated_storage
  end

  def vms_used
    tenant.active_vms.count
  end

  def templates_used
    tenant.miq_templates.count
  end

  # remove all quotas that are not listed in the keys to keep
  # e.g.: tenant.tenant_quotas.destroy_missing_quotas(include_keys)
  # NOTE: these are already local, no need to hit db to find them
  def self.destroy_missing(keep)
    keep = keep.map(&:to_s)
    deletes = all.select { |tq| !keep.include?(tq.name) }
    delete(deletes)
  end

  def quota_hash
    self.class.quota_definitions[name.to_sym].merge(:unit => unit, :value => value, :warn_value => warn_value, :format => format) # attributes
  end

  def format
    self.class.quota_definitions.fetch_path(name.to_sym, :format).to_s
  end

  def default_unit
    self.class.quota_definitions.fetch_path(name.to_sym, :unit).to_s
  end

  def check_for_over_allocation
    return unless value_changed?

    # Root tenant has no (unlimited) quota
    # First level tenant can also have unlimited quota
    return if tenant.root? || tenant.parent.root?

    oval, nval = changes["value"]

    # Check that the new value is >= the amount that was already allocated to child tenants
    if nval < allocated
      errors.add(name, "quota is over allocated, #{nval} was requested but only #{nval - allocated} is available")
      return
    end

    # Check that new quota is a least as much as was already used
    if nval < used
      errors.add(name, "quota is under allocated, #{nval} was requested but #{used} has already been used")
      return
    end

    diff = (nval || 0) - (oval || 0)

    # Check if the parent has enough quota available to give to the child
    parent_quota = tenant.parent.tenant_quotas.send(name).take
    unless parent_quota.nil?
      if parent_quota.available < diff
        errors.add(name, "quota is over allocated, parent tenant does not have enough quota")
      end
    end