#ruby-on-rails #ruby #ruby-hash
#ruby-on-rails #ruby #ruby-hash
Вопрос:
У меня есть некоторые константы, определенные следующим образом
CONSUMER_TYPE = 'consumer'
CONSUMER_1_TYPE = "#{CONSUMER_TYPE}1"
CONSUMER_2_TYPE = "#{CONSUMER_TYPE}2"
CONSUMER_3_TYPE = "#{CONSUMER_TYPE}3"
INDUSTRIAL_TYPE = 'industrial'
INDUSTRIAL_1_TYPE = "#{INDUSTRIAL_TYPE}1"
INDUSTRIAL_2_TYPE = "#{INDUSTRIAL_TYPE}2"
INDUSTRIAL_3_TYPE = "#{INDUSTRIAL_TYPE}3"
SERVICES_TYPE = 'services'
SERVICES_1_TYPE = "#{SERVICES_TYPE}1"
SERVICES_2_TYPE = "#{SERVICES_TYPE}2"
SERVICES_3_TYPE = "#{SERVICES_TYPE}3"
Поле записи может иметь такие значения, как services2
или industrial1
. В моей модели я создал метод сопоставления, который должен возвращать хэш с разным набором атрибутов в зависимости от значения поля записи, например
def classification_attributes
product_type_mapping[product_type]
end
def product_type_mapping
{
CONSUMER_1_TYPE => { abc: abc, vpn: vpn, lbc: lbc },
CONSUMER_2_TYPE => { abc: abc, vpn: vpn, lbc: lbc },
CONSUMER_3_TYPE => { abc: abc, vpn: vpn, lbc: lbc },
INDUSTRIAL_1_TYPE => { vpn: vpn, htt: htt, bnn: bnn },
INDUSTRIAL_2_TYPE => { vpn: vpn, htt: htt, bnn: bnn },
INDUSTRIAL_3_TYPE => { vpn: vpn, htt: htt, bnn: bnn },
SERVICES_1_TYPE => { dhy: dhy, rtt: rtt, abc: abc },
SERVICES_2_TYPE => { dhy: dhy, rtt: rtt, abc: abc },
SERVICES_3_TYPE => { dhy: dhy, rtt: rtt, abc: abc }
}
end
Например, если запись содержит значение consumer3
, метод сопоставления должен вернуть { abc: abc, vpn: vpn, lbc: lbc }
. Как вы можете видеть, существует много дублирования кода. Мне было интересно, может ли быть более оптимальный и краткий способ решения этой задачи.
Комментарии:
1. Вы выбрали ключи? Почему не
classification_attributes
принимает аргумент?2. Затем я объединяю
classification_attributes
хэш с основнымbase_attributes
.base_attributes.merge(classification_attributes)
Ответ №1:
- Используйте символы вместо констант.
- Не раскрывайте сопоставление.
Константы в Ruby в основном предназначены для сокрытия информации. Например, если ключ изменяется с consumer1
на до consumer_1
тех пор, пока все обращается к хэшу, с CONSUMER_1_TYPE
вами все в порядке. Зачем рисковать?
Вместо этого полностью скройте хэш. Теперь, когда он скрыт, константы не нужны. Используйте символы.
Если все значения будут одинаковыми, поместите их в свои собственные методы.
def classification_attributes(product_type)
product_type_mapping[product_type]
end
private def consumer_config
{ abc: abc, vpn: vpn, lbc: lbc }
end
private def industrial_config
{ vpn: vpn, htt: htt, bnn: bnn }
end
private def services_config
{ dhy: dhy, rtt: rtt, abc: abc }
end
private def product_type_mapping
{
conumser1: consumer_config,
consumer2: consumer_config,
consumer3: consumer_config,
industrial1: industrial_config,
industrial2: industrial_config,
industrial3: industrial_config,
services1: services_config,
services2: services_config,
services3: services_config
}
end
Это все, что я могу сказать без дополнительного контекста. При такой избыточности вы можете разделить product_type
на тип и подтип.
Рассмотрите возможность перехода product_type_mapping
в config/application.rb, а также любые другие связанные конфигурации. Это сохраняет конфигурацию приложения в одном месте, а не разбросано по разным классам.
module YourApp
class Application < Rails::Application
config.x.consumer_config = { abc: abc, vpn: vpn, lbc: lbc }.freeze
config.x.industrial_config = { vpn: vpn, htt: htt, bnn: bnn }.freeze
config.x.services_config = { dhy: dhy, rtt: rtt, abc: abc }.freeze
config.x.product_type_mapping = {
conumser1: config.x.consumer_config,
consumer2: config.x.consumer_config,
consumer3: config.x.consumer_config,
industrial1: config.x.industrial_config,
industrial2: config.x.industrial_config,
industrial3: config.x.industrial_config,
services1: config.x.services_config,
services2: config.x.services_config,
services3: config.x.services_config
}.freeze
end
end
# in your class...
def classification_attributes(product_type)
Rails.configuration.x.product_type_mapping[product_type]
end
Комментарии:
1. Спасибо. Я выбираю ключи, поэтому
consumer1
consumer_1
преобразование невозможно.