Module: InteractorSupport::Validations

Extended by:
ActiveSupport::Concern
Includes:
Core
Defined in:
lib/interactor_support/validations.rb

Overview

Provides context-aware validation DSL for interactors.

This module adds ActiveModel::Validations and wraps it with methods like required, optional, validates_before, and validates_after, allowing declarative validation of interactor context values.

Validations are executed automatically before (or after) the interactor runs.

Examples:

Required attributes with ActiveModel rules

required :email, :name
required age: { numericality: { greater_than: 18 } }

Optional attributes with presence/format validations

optional bio: { length: { maximum: 500 } }

Type and inclusion validation before execution

validates_before :role, type: String, inclusion: { in: %w[admin user guest] }

Persistence validation after execution

validates_after :user, persisted: true

See Also:

  • ActiveModel::Validations

Instance Method Summary collapse

Methods included from Core

included

Instance Method Details

#apply_custom_validations(key, validations) ⇒ Object

Applies custom inline validations to a context key.

Parameters:

  • key (Symbol)

    the context key

  • validations (Hash)

    options like presence:, type:, inclusion:, persisted:



143
144
145
146
147
148
# File 'lib/interactor_support/validations.rb', line 143

def apply_custom_validations(key, validations)
  validation_for_presence(key) if validations[:presence]
  validation_for_inclusion(key, validations[:inclusion]) if validations[:inclusion]
  validation_for_persistence(key) if validations[:persisted]
  validation_for_type(key, validations[:type]) if validations[:type]
end

#validation_for_inclusion(key, inclusion) ⇒ Object

Fails if value is not included in allowed values.

Parameters:

  • key (Symbol)
  • inclusion (Hash)

    with :in key



164
165
166
167
168
169
170
171
172
# File 'lib/interactor_support/validations.rb', line 164

def validation_for_inclusion(key, inclusion)
  unless inclusion.is_a?(Hash) && inclusion[:in].is_a?(Enumerable)
    raise ArgumentError, 'inclusion validation requires an :in key with an array or range'
  end

  context.fail!(errors: ["#{key} was not in the specified inclusion"]) unless inclusion[:in].include?(context[key])
rescue ArgumentError => e
  context.fail!(errors: [e.message])
end

#validation_for_persistence(key) ⇒ Object

Fails if value is not a persisted ApplicationRecord.

Parameters:

  • key (Symbol)


186
187
188
189
190
191
192
193
194
# File 'lib/interactor_support/validations.rb', line 186

def validation_for_persistence(key)
  validation_for_presence(key)

  unless context[key].is_a?(ApplicationRecord)
    context.fail!(errors: ["#{key} is not an ApplicationRecord, which is required for persisted validation"])
  end

  context.fail!(errors: ["#{key} was not persisted"] + context[key].errors.full_messages) unless context[key].persisted?
end

#validation_for_presence(key) ⇒ Object

Fails if value is nil or blank.

Parameters:

  • key (Symbol)


178
179
180
# File 'lib/interactor_support/validations.rb', line 178

def validation_for_presence(key)
  context.fail!(errors: ["#{key} does not exist"]) unless context[key].present?
end

#validation_for_type(key, type) ⇒ Object

Fails if context value is not of expected type.

Parameters:

  • key (Symbol)
  • type (Class)


155
156
157
# File 'lib/interactor_support/validations.rb', line 155

def validation_for_type(key, type)
  context.fail!(errors: ["#{key} was not of type #{type}"]) unless context[key].is_a?(type)
end