Class: SecIdValidator

Inherits:
ActiveModel::EachValidator
  • Object
show all
Defined in:
lib/sec_id/active_model.rb

Overview

ActiveModel validator for securities identifiers, registered under the sec_id key.

It validates a value against a single type (type:), an allowlist (types:), or any of the supported identifier types (no key). Validation is strict by default; separator-lenient canonicalization and specific failure reasons are opt-in via normalize: and details:.

This file is loaded automatically inside Rails (via SecID::Railtie) and must be required explicitly (require 'sec_id/active_model') in non-Rails ActiveModel stacks. It is never on the default require 'sec_id' path, so the gem keeps its zero runtime dependencies.

Examples:

Validate a single type

validates :isin, sec_id: { type: :isin }

Validate against an allowlist

validates :ref, sec_id: { types: %i[isin cusip] }

Validate against any supported type

validates :ref, sec_id: true

Constant Summary collapse

DEFAULT_MESSAGE =

Built-in English default; %{type_name} is interpolated by ActiveModel/I18n (template token syntax is required here, hence the cop disable).

'is not a valid %{type_name}'

Instance Method Summary collapse

Instance Method Details

#check_validity!void

This method returns an undefined value.

Validates the validator's own options at class-load time (fail-fast on misconfiguration).

Raises:

  • (ArgumentError)

    if both type: and types: are given, or a named type is unknown



42
43
44
45
46
47
# File 'lib/sec_id/active_model.rb', line 42

def check_validity!
  raise ArgumentError, 'Pass either :type or :types, not both' if options[:type] && options[:types]
  raise ArgumentError, ':types cannot be empty' if options[:types] && configured_types.empty?

  configured_types&.each { |type| SecID[type] }
end

#validate_each(record, attribute, value) ⇒ void

This method returns an undefined value.

Validates value and, with normalize: true, rewrites it to canonical form on success.

Parameters:

  • record (ActiveModel::Validations)

    the record being validated

  • attribute (Symbol)

    the attribute being validated

  • value (Object)

    the attribute value



55
56
57
58
59
60
61
62
63
# File 'lib/sec_id/active_model.rb', line 55

def validate_each(record, attribute, value)
  return if valid_value?(record, attribute, value)

  record.errors.add(
    attribute, :sec_id,
    message: options[:message] || detail_reason(value) || DEFAULT_MESSAGE,
    type_name: human_type_name
  )
end