Configuração de host de provedor de API convencional DRY por fallback de ambiente e mapeamento de alias

Para o meu gem de sistema de gerenciamento de conteúdo http://Home-Page.Software, eu queria oferecer suporte a diferentes APIs e usar o host certo para o ambiente atual por uma cadeia de fallback.
Portanto, preciso lidar com aliases de nomes de ambiente de usuário e ambientes não suportados por um provedor de API.

Dadas essas configurações de um inicializador Rails alimentado por rails-settings-cached (você tem que usar desenvolvimento, teste, teste ou produção como chave):

Setting.defaults[
'apis.providers.volontariat.hosts.development'
] = 'http://localhost:3001'
Setting.defaults[
'apis.providers.volontariat.hosts.production'
] = 'http://Volontari.at' # currently down :-(

Eu queria algo assim:

host = ApiProviderHost.new('volontariat', Rails.env).to_s

Espero que se comporte assim:

describe ApiProviderHost do
describe
'#to_s' do
it
'behaves like this' do
provider
= 'name_of_host'
Setting.defaults[
'apis.providers.name_of_host.hosts.development'
] = 'http://localhost:3001'

# no fallback or alias mapping needed
expect
(
described_class
.new(provider, 'development').to_s
).to be == 'http://localhost:3001'

# fallback to development
expect
(
described_class
.new(provider, 'test').to_s
).to be == 'http://localhost:3001'

# alias mapping needed
expect
(
described_class
.new(provider, 'dev').to_s
).to be == 'http://localhost:3001'

# alias not found
expect
{
described_class
.new(provider, 'unknown_environment').to_s
}.to raise_error(
NotImplementedError,
'Your environment is unknown. Please update alias mapping!'
)

# environment not supported by provider
expect
{
described_class
.new(provider, 'staging').to_s
}.to raise_error(
NotImplementedError,
'The API provider does not support your environment!'
)
end
end
end

E eu implementei esta aula:

class ApiProviderHost
ENVIRONMENTS
= [:development, :test, :staging, :production]
ALIASES
= {
dev
: :development, testing: :test, stage: :staging, show: :staging,
live
: :production, prod: :production
}
FALLBACKS
= {
development
: [:development, :test, :staging, :production],
test
: [:test, :development, :staging, :production],
staging
: [:staging, :production],
production
: [:production]
}

def initialize(provider, working_environment)
@provider = provider
@environment = working_environment.to_s.to_sym
end

def setting_namespace
"apis.providers.#{@provider}.hosts"
end

def environment
if ENVIRONMENTS.include?(@environment)
@environment
else
ALIASES
[@environment] || raise(
NotImplementedError,
'Your environment is unknown. Please update alias mapping!'
)
end
end

def to_s
host
= nil

FALLBACKS
[environment].each do |provider_environment|
host
= Setting["#{setting_namespace}.#{provider_environment}"]

break if host
end

unless host
raise
(
NotImplementedError,
'The API provider does not support your environment!'
)
end

host

end
end

PS: No passado eu vivia sempre configurando um host para cada ambiente e sem mapeamento de alias de ambiente, mas isso não era SECO :

Setting.defaults[
'apis.providers.volontariat.hosts.development'
] = 'http://localhost:3001'
Setting.defaults[
'apis.providers.volontariat.hosts.test'
] = 'http://localhost:3001'
Setting.defaults[
'apis.providers.volontariat.hosts.staging'
] = 'http://Volontari.at'
Setting.defaults[
'apis.providers.volontariat.hosts.production'
] = 'http://Volontari.at'

# optional: I also put the little envionment alias mapping code here if you can't live without it
environment
= {
dev
: :development, testing: :test, stage: :staging, show: :staging,
live
: :production, prod: :production
}[Rails.env.to_s.to_sym] || Rails.env
host
= Setting[
"apis.providers.volontariat.hosts.#{environment}"
]