class Card::Codename

{Card}‘s names can be changed, and therefore names should not be directly mentioned in code, lest a name change break the application.

Instead, a {Card} that needs specific code manipulations should be given a {Codename}, which will not change even if the card’s name does.

An administrator might add to the Company card via the RESTful web API with a url like

/update/CARDNAME?card[codename]=CODENAME

…or via the api like

Card[CARDNAME].update! codename: CODENAME

Generally speaking, codenames are represented by Symbols.

The {Codename} class provides a fast cache for this slow-changing data. Every process maintains a complete cache that is not frequently reset

Public Class Methods

[](codename) click to toggle source

returns codename for id and id for codename @param codename [Integer, Symbol, String, Card::Name] @return [Symbol]

# File lib/card/codename.rb, line 27
def [] codename
  case codename
  when Integer
    codehash[codename]
  when Symbol, String
    codehash.key?(codename.to_sym) ? codename.to_sym : nil
  end
end
card(codename) { || ... } click to toggle source
# File lib/card/codename.rb, line 49
def card codename
  if (card_id = id(codename))
    Card[card_id]
  elsif block_given?
    yield
  end
end
codehash() click to toggle source

a Hash in which Symbol keys have Integer values and vice versa @return [Hash]

# File lib/card/codename.rb, line 65
def codehash
  @codehash ||= load_codehash
end
exist?(codename) click to toggle source
# File lib/card/codename.rb, line 57
def exist? codename
  id(codename).present?
end
Also aliased as: exists?
exists?(codename)
Alias for: exist?
generate_id_constants() click to toggle source
# File lib/card/codename.rb, line 87
def generate_id_constants
  # If a card has the codename _example_, then Card::ExampleID will
  # return the id for that card.
  codehash.each do |codename, id|
    next unless codename.is_a?(Symbol) && !codename.to_s.match?(/\W/)

    id_constant codename, id
  end
end
id(codename) click to toggle source
# File lib/card/codename.rb, line 36
def id codename
  case codename
  when Symbol, String
    codehash[codename.to_sym]
  when Integer
    codehash.key?(codename) ? codename : nil
  end
end
id!(codename) click to toggle source

@param codename [Symbol, String] @return [Integer]

# File lib/card/codename.rb, line 77
def id! codename
  id(codename) || unknown_codename!(codename)
end
name(codename=nil) click to toggle source
# File lib/card/codename.rb, line 45
def name codename=nil
  id(codename)&.cardname
end
name!(codename) click to toggle source

@param codename [Symbol, String] @return [Card::Name]

# File lib/card/codename.rb, line 83
def name! codename
  id!(codename)&.cardname
end
recode(oldcode, newcode) click to toggle source
# File lib/card/codename.rb, line 97
def recode oldcode, newcode
  return unless id(oldcode) && !id(newcode)

  puts "recode #{oldcode}, #{newcode}"
  Card.where(codename: oldcode).take.update_column :codename, newcode
  reset_cache
end
reset_cache() click to toggle source

clear cache both locally and in cache

# File lib/card/codename.rb, line 70
def reset_cache
  @codehash = nil
  ::Card.cache.delete "CODEHASH"
end

Private Class Methods

check_duplicates(codehash, codename, card_id) click to toggle source

@todo remove duplicate checks here; should be caught upon creation

# File lib/card/codename.rb, line 118
def check_duplicates codehash, codename, card_id
  return unless codehash.key?(codename) || codehash.key?(card_id)

  Rails.logger.debug "dup codename: #{codename}, "\
                     "ID:#{card_id} (#{codehash[codename]})"
end
each_codenamed_card() { |to_sym, to_i| ... } click to toggle source

iterate through every card with a codename @yieldparam codename [Symbol] @yieldparam id [Integer]

# File lib/card/codename.rb, line 110
def each_codenamed_card
  sql = "select id, codename from cards where codename is not NULL"
  ActiveRecord::Base.connection.select_all(sql).each do |row|
    yield row["codename"].to_sym, row["id"].to_i
  end
end
generate_codehash() click to toggle source
# File lib/card/codename.rb, line 132
def generate_codehash
  hash = {}
  each_codenamed_card do |codename, card_id|
    check_duplicates hash, codename, card_id
    hash[codename] = card_id
    hash[card_id] = codename
  end
  hash
end
id_constant(codename, id=nil) click to toggle source
# File lib/card/codename.rb, line 147
def id_constant codename, id=nil
  id ||= id! codename
  Card.const_get_or_set("#{codename.to_s.camelize}ID") { id }
end
load_codehash() click to toggle source

generate Hash for @codehash and put it in the cache

# File lib/card/codename.rb, line 126
def load_codehash
  ::Card.cache.fetch("CODEHASH") do
    generate_codehash
  end
end
unknown_codename!(mark) click to toggle source
# File lib/card/codename.rb, line 142
def unknown_codename! mark
  raise Card::Error::CodenameNotFound,
        ::I18n.t(:lib_exception_unknown_codename, codename: mark)
end