Class: Servactory::ToolKit::DynamicOptions::Target
- Defined in:
- lib/servactory/tool_kit/dynamic_options/target.rb
Overview
Validates that Class-typed attribute value matches one of the target classes.
## Purpose
Target provides class matching validation for Class-typed attributes. It ensures that the passed class is one of the specified target classes, supporting both single class and arrays of acceptable classes. This is useful for validating service classes, strategy patterns, or any scenario where specific classes are expected.
## Usage
This option is **NOT included by default**. Register it for each attribute type where you want to use it:
“‘ruby configuration do
input_option_helpers([
Servactory::ToolKit::DynamicOptions::Target.use
])
internal_option_helpers([
Servactory::ToolKit::DynamicOptions::Target.use
])
output_option_helpers([
Servactory::ToolKit::DynamicOptions::Target.use
])
end “‘
Use in your service definition:
“‘ruby class ProcessOrderService < ApplicationService::Base
input :service_class, type: Class, target: UserService
input :handler_class, type: Class, target: [CreateHandler, UpdateHandler]
end “‘
## Simple Mode
Specify target class directly or as an array:
“‘ruby input :service_class, type: Class, target: UserService input :handler_class, type: Class, target: [CreateHandler, UpdateHandler] “`
## Advanced Mode
Specify target with custom error message using a hash. Note: Advanced mode uses ‘:in` key (not `:is`).
With static message:
“‘ruby input :handler_class, type: Class, target:
in: [CreateHandler, UpdateHandler],
message: "Input `handler_class` must be one of: CreateHandler, UpdateHandler"
“‘
With dynamic lambda message:
“‘ruby input :handler_class, type: Class, target:
in: [CreateHandler, UpdateHandler],
message: lambda do |input:, value:, option_value:, **|
"Input `#{input.name` received `#value`, expected: #')"
end
} “‘
Lambda receives the following parameters:
-
For inputs: ‘input:, value:, option_value:, reason:, **`
-
For internals: ‘internal:, value:, option_value:, reason:, **`
-
For outputs: ‘output:, value:, option_value:, reason:, **`
## Validation Rules
-
Class must exactly match one of the target classes
-
Supports single class or array of classes
-
Optional inputs with nil value validate against default
## Important Notes
-
Use ‘target: { in: […] }` syntax for specifying allowed values
-
Returns ‘:invalid_option` error if target is nil
-
For optional inputs with nil value and default, validates the default
-
Internal/output attributes do NOT have default value handling (unlike inputs)
-
For Class-typed attributes, arrays of classes are preserved as-is rather than being wrapped (e.g., ‘[User, Admin]` stays as array, not `[[User, Admin]]`)
Class Method Summary collapse
-
.use(option_name = :target) ⇒ Servactory::Maintenance::Attributes::OptionHelper
Creates a Target validator instance.
Instance Method Summary collapse
-
#condition_for_input_with(input:, value:, option:) ⇒ Boolean, Array
Validates target condition for input attribute.
-
#condition_for_internal_with(value:, option:, internal: nil) ⇒ Boolean, Array
Validates target condition for internal attribute.
-
#condition_for_output_with(value:, option:, output: nil) ⇒ Boolean, Array
Validates target condition for output attribute.
-
#message_for_input_with(service:, input:, value:, option_name:, option_value:, reason:) ⇒ String
Generates error message for input validation failure.
-
#message_for_internal_with(service:, internal:, value:, option_name:, option_value:, reason:) ⇒ String
Generates error message for internal validation failure.
-
#message_for_output_with(service:, output:, value:, option_name:, option_value:, reason:) ⇒ String
Generates error message for output validation failure.
Methods inherited from Must
#equivalent_with, #initialize, #must, #must_content_message_with, #must_content_value_with, #must_content_with
Constructor Details
This class inherits a constructor from Servactory::ToolKit::DynamicOptions::Must
Class Method Details
.use(option_name = :target) ⇒ Servactory::Maintenance::Attributes::OptionHelper
Creates a Target validator instance.
104 105 106 107 |
# File 'lib/servactory/tool_kit/dynamic_options/target.rb', line 104 def self.use(option_name = :target) instance = new(option_name, :in) instance.must(:"be_#{option_name}") end |
Instance Method Details
#condition_for_input_with(input:, value:, option:) ⇒ Boolean, Array
Validates target condition for input attribute.
115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/servactory/tool_kit/dynamic_options/target.rb', line 115 def condition_for_input_with(input:, value:, option:) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity return [false, :invalid_option] if option.value.nil? target_values = normalize_target_values(option.value, input.types) # Required inputs or optional with non-nil value. return target_values.include?(value) if input.required? || (input.optional? && !value.nil?) # Optional with nil value but has default. return target_values.include?(input.default) if input.optional? && value.nil? && !input.default.nil? true end |
#condition_for_internal_with(value:, option:, internal: nil) ⇒ Boolean, Array
Validates target condition for internal attribute.
135 136 137 138 139 140 141 |
# File 'lib/servactory/tool_kit/dynamic_options/target.rb', line 135 def condition_for_internal_with(value:, option:, internal: nil, **) return [false, :invalid_option] if option.value.nil? target_values = normalize_target_values(option.value, internal.types) target_values.include?(value) end |
#condition_for_output_with(value:, option:, output: nil) ⇒ Boolean, Array
Validates target condition for output attribute.
149 150 151 152 153 154 155 |
# File 'lib/servactory/tool_kit/dynamic_options/target.rb', line 149 def condition_for_output_with(value:, option:, output: nil, **) return [false, :invalid_option] if option.value.nil? target_values = normalize_target_values(option.value, output.types) target_values.include?(value) end |
#message_for_input_with(service:, input:, value:, option_name:, option_value:, reason:) ⇒ String
Generates error message for input validation failure.
168 169 170 171 172 173 174 175 176 177 178 179 |
# File 'lib/servactory/tool_kit/dynamic_options/target.rb', line 168 def (service:, input:, value:, option_name:, option_value:, reason:, **) i18n_key = "inputs.validations.must.dynamic_options.target" i18n_key += reason.present? ? ".#{reason}" : ".default" service.translate( i18n_key, input_name: input.name, value: value.inspect, expected_target: option_value.inspect, option_name: ) end |
#message_for_internal_with(service:, internal:, value:, option_name:, option_value:, reason:) ⇒ String
Generates error message for internal validation failure.
190 191 192 193 194 195 196 197 198 199 200 201 |
# File 'lib/servactory/tool_kit/dynamic_options/target.rb', line 190 def (service:, internal:, value:, option_name:, option_value:, reason:, **) i18n_key = "internals.validations.must.dynamic_options.target" i18n_key += reason.present? ? ".#{reason}" : ".default" service.translate( i18n_key, internal_name: internal.name, value: value.inspect, expected_target: option_value.inspect, option_name: ) end |
#message_for_output_with(service:, output:, value:, option_name:, option_value:, reason:) ⇒ String
Generates error message for output validation failure.
212 213 214 215 216 217 218 219 220 221 222 223 |
# File 'lib/servactory/tool_kit/dynamic_options/target.rb', line 212 def (service:, output:, value:, option_name:, option_value:, reason:, **) i18n_key = "outputs.validations.must.dynamic_options.target" i18n_key += reason.present? ? ".#{reason}" : ".default" service.translate( i18n_key, output_name: output.name, value: value.inspect, expected_target: option_value.inspect, option_name: ) end |