Skip to content

Динамические опции Начиная с 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:

ruby
Servactory::ToolKit::DynamicOptions::Format.use(
  formats: {
    email: {
      pattern: /@/,
      validator: ->(value:) { value.present? }
    },
    invoice: {
      pattern: /^([A]{2})-([0-9A-Z]{6})$/,
      validator: ->(value:) { value.present? }
    }
  }
)

Установка и использование

ruby
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
])
ruby
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
  • Включено по умолчанию: Нет
  • Исходный код

Установка и использование

ruby
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
])
ruby
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
  • Включено по умолчанию: Нет
  • Исходный код

Установка и использование

ruby
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
])
ruby
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
  • Включено по умолчанию: Нет
  • Исходный код

Установка и использование

ruby
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
])
ruby
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 вашего проекта.

Шаблон

ruby
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

Применение

ruby
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)
])