Динамические опции Начиная с 2.4.0
Динамические опции — это дополнительные опции, основанные на must
, которые могут принимать значения в виде аргументов. Динамические опции похожи на пользовательские хелперы, но отличает их друг от друга возможность работать с аргументами.
Servactory из коробки предоставляет следующий набор динамических опций:
consists_of
;format
;min
;max
;multiple_of
.
По умолчанию включена только опция consists_of
. Для работы остальных необходимо применить готовые наборы в конфигурации хелперов опций для каждого из существующих атрибутов.
Готовые опции
Опция consists_of
Начиная с 2.6.0
- Набор:
Servactory::ToolKit::DynamicOptions::ConsistsOf
- Основан на:
must
- Включено по умолчанию: Да
- Исходный код
Опция format
- Набор:
Servactory::ToolKit::DynamicOptions::Format
- Основан на:
must
- Включено по умолчанию: Нет
- Исходный код
Поддерживаемые форматы
uuid
;email
;password
;duration
;date
;time
;datetime
;boolean
.
Кастомизация
Вы можете перезаписывать существующие форматы и добавлять собственные. Для этого воспользуйтесь атрибутом formats
в методе use
:
Servactory::ToolKit::DynamicOptions::Format.use(
formats: {
email: {
pattern: /@/,
validator: ->(value:) { value.present? }
},
invoice: {
pattern: /^([A]{2})-([0-9A-Z]{6})$/,
validator: ->(value:) { value.present? }
}
}
)
Установка и использование
input_option_helpers([
Servactory::ToolKit::DynamicOptions::Min.use
])
internal_option_helpers([
Servactory::ToolKit::DynamicOptions::Min.use(:minimum)
])
output_option_helpers([
Servactory::ToolKit::DynamicOptions::Min.use
])
input :email,
type: String,
format: :email
internal :email,
type: String,
format: { is: :email }
output :data,
type: String,
format: {
is: :email,
message: lambda do |output:, value:, option_value:, **|
"Incorrect `email` format in `#{output.name}`"
end
}
Опция min
- Набор:
Servactory::ToolKit::DynamicOptions::Min
- Основан на:
must
- Включено по умолчанию: Нет
- Исходный код
Установка и использование
input_option_helpers([
Servactory::ToolKit::DynamicOptions::Min.use
])
internal_option_helpers([
Servactory::ToolKit::DynamicOptions::Min.use(:minimum)
])
output_option_helpers([
Servactory::ToolKit::DynamicOptions::Min.use
])
input :data,
type: Integer,
min: 1
internal :data,
type: String,
minimum: { is: 1 }
output :data,
type: Array,
min: {
is: 1,
message: lambda do |output:, value:, option_value:, **|
"The size of the `#{output.name}` value must be greater than or " \
"equal to `#{option_value}` (got: `#{value}`)"
end
}
Опция max
- Набор:
Servactory::ToolKit::DynamicOptions::Max
- Основан на:
must
- Включено по умолчанию: Нет
- Исходный код
Установка и использование
input_option_helpers([
Servactory::ToolKit::DynamicOptions::Max.use
])
internal_option_helpers([
Servactory::ToolKit::DynamicOptions::Max.use(:maximum)
])
output_option_helpers([
Servactory::ToolKit::DynamicOptions::Max.use
])
input :data,
type: Integer,
max: 10
internal :data,
type: String,
maximum: { is: 10 }
output :data,
type: Array,
max: {
is: 10,
message: lambda do |output:, value:, option_value:, **|
"The size of the `#{output.name}` value must be less than or " \
"equal to `#{option_value}` (got: `#{value}`)"
end
}
Опция multiple_of
- Набор:
Servactory::ToolKit::DynamicOptions::MultipleOf
- Основан на:
must
- Включено по умолчанию: Нет
- Исходный код
Установка и использование
input_option_helpers([
Servactory::ToolKit::DynamicOptions::MultipleOf.use
])
internal_option_helpers([
Servactory::ToolKit::DynamicOptions::MultipleOf.use(:divisible_by)
])
output_option_helpers([
Servactory::ToolKit::DynamicOptions::MultipleOf.use
])
input :data,
type: Integer,
multiple_of: 2
internal :data,
type: Integer,
divisible_by: { is: 2 }
output :data,
type: Float,
multiple_of: {
is: 2,
message: lambda do |output:, value:, option_value:, **|
"Output `#{output.name}` has the value `#{value}`, " \
"which is not a multiple of `#{option_value}`"
end
}
Пользовательские опции
Вы можете создавать собственные динамические опции.
Используйте подготовленный шаблон, который предоставлен ниже, для реализации собственной динамической опции.
Рекомендуется расположить файл класса в директории app/services/application_service/dynamic_options
вашего проекта.
Шаблон
module ApplicationService
module DynamicOptions
class MyOption < Servactory::ToolKit::DynamicOptions::Must
def self.use(option_name = :my_option, **options)
new(option_name).must(:be_the_best)
end
def condition_for_input_with(input:, value:, option:)
# Здесь должны быть условия, предназначенные для атрибута input
end
def condition_for_internal_with(internal:, value:, option:)
# Здесь должны быть условия, предназначенные для атрибута internal
end
def condition_for_output_with(output:, value:, option:)
# Здесь должны быть условия, предназначенные для атрибута output
end
def message_for_input_with(service:, input:, value:, option_value:, **)
# Здесь должен быть текст сообщения на случай, если условие не будет соблюдено
end
def message_for_internal_with(service:, internal:, value:, option_value:, **)
# Здесь должен быть текст сообщения на случай, если условие не будет соблюдено
end
def message_for_output_with(service:, output:, value:, option_value:, **)
# Здесь должен быть текст сообщения на случай, если условие не будет соблюдено
end
end
end
end
Применение
input_option_helpers([
ApplicationService::DynamicOptions::MyOption.use
])
internal_option_helpers([
ApplicationService::DynamicOptions::MyOption.use(:my_best_option)
])
output_option_helpers([
ApplicationService::DynamicOptions::MyOption.use(some: :data)
])