Class: MetadataPresenter::BaseValidator Abstract

Inherits:
Object
  • Object
show all
Defined in:
app/validators/metadata_presenter/base_validator.rb

Overview

This class is abstract.

Abstract base class for validation utilities. Provides an interface for implementing validation from the metadata.

The Base validator expects the subclass to implement only #invalid_answer? as long the conventions are followed:

  1. The default metadata for error messages follows the “error.name_of_the_class_without_validator”

  2. The class should have the same name as the schema e.g ‘required’ will lookup for RequiredValidator.

On the example below the base validator will look for the custom message on “errors” -> “grogu” -> “any” and if there is none, then will look for the default message on default metadata as “error.grogu”.

Examples:

Custom validator

class GroguValidator < BaseValidator
  def invalid_answer?
    user_answer = answers[component.name]

    user_answer.to_s == 'Grogu'
  end
end

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(page_answers:, component:) ⇒ BaseValidator

Returns a new instance of BaseValidator.



35
36
37
38
# File 'app/validators/metadata_presenter/base_validator.rb', line 35

def initialize(page_answers:, component:)
  @page_answers = page_answers
  @component = component
end

Instance Attribute Details

#componentMetadataPresenter::Component (readonly)

Returns component object from the metadata.

Returns:



33
34
35
# File 'app/validators/metadata_presenter/base_validator.rb', line 33

def component
  @component
end

#page_answersMetadataPresenter::PageAnswers (readonly)

Returns page answers object.

Returns:



30
31
32
# File 'app/validators/metadata_presenter/base_validator.rb', line 30

def page_answers
  @page_answers
end

Instance Method Details

#allow_blank?Boolean

Method signature to be overwrite in the subclass if you do not want to allow blank values. We should not allow blank when performing the required validation.

Returns:

  • (Boolean)


144
145
146
# File 'app/validators/metadata_presenter/base_validator.rb', line 144

def allow_blank?
  user_answer.blank? && !self.class.name.demodulize.include?('RequiredValidator')
end

#custom_error_messageString

The custom message will be lookup from the schema key on the metadata. Assuming for example that the schema key is ‘grogu’ then the message will lookup for ‘errors.grogu.any’.

Returns:

  • (String)

    message from the service metadata



57
58
59
60
61
# File 'app/validators/metadata_presenter/base_validator.rb', line 57

def custom_error_message
  message = component.dig('errors', schema_key, 'any')

  message % error_message_hash if message.present?
end

#default_error_message(params = {}) ⇒ String

The default error message will be look using the schema key. Assuming the schema key is ‘grogu’ then the default message will look for ‘error.grogu.value:en’ or ‘error.grogu.value:cy’.

is not present

Returns:

  • (String)

    returns the default error message

Raises:



76
77
78
79
80
81
82
83
84
85
86
87
# File 'app/validators/metadata_presenter/base_validator.rb', line 76

def default_error_message(params = {})
  default_error_message_key = "error.#{schema_key}"
  default_message = Rails.application
                         .config
                         .[default_error_message_key]

  if default_message.present?
    default_message[error_key] % error_message_hash.merge(params)
  else
    raise NoDefaultMessage, "No default '#{error_key}' message found for key '#{default_error_message_key}'."
  end
end

#error_keyString

The key to use when retrieving localised error messages. This key will be ‘value:locale` i.e. `value:en` for English or `value:cy` for Welsh.

Returns:

  • (String)

    value key to be looked in the default error metadata



115
116
117
# File 'app/validators/metadata_presenter/base_validator.rb', line 115

def error_key
  @error_key ||= ['value', I18n.locale].join(':').freeze
end

#error_message_hashObject

Error message hash that will be interpolate with the custom message or the default metadata

The message could include ‘%control’ to add the label name. Or for the GroguValidator will be ‘%grogu’ and the value setup in the metadata.



125
126
127
128
129
130
# File 'app/validators/metadata_presenter/base_validator.rb', line 125

def error_message_hash
  {
    control: component.humanised_title,
    schema_key.to_sym => validation_value
  }
end

#invalid_answer?TrueClass, FalseClass

Needs to be implemented on the subclass

Returns:

  • (TrueClass)

    if is invalid

  • (FalseClass)

    if is valid

Raises:

  • (NotImplementedError)


94
95
96
# File 'app/validators/metadata_presenter/base_validator.rb', line 94

def invalid_answer?
  raise NotImplementedError
end

#schema_keyString

The convention to be looked on the metadata is by the name of the class. E.g the GroguValidator will look for ‘grogu’ on the metadata. Overwrite this method if the validator doesn’t follow the convetions.

default metadata

Returns:

  • (String)

    schema key to be looked on the metadata and in the



105
106
107
# File 'app/validators/metadata_presenter/base_validator.rb', line 105

def schema_key
  @schema_key ||= self.class.name.demodulize.gsub('Validator', '').underscore
end

#user_answerString

Returns user answer for the specific component.

Returns:

  • (String)

    user answer for the specific component



65
66
67
# File 'app/validators/metadata_presenter/base_validator.rb', line 65

def user_answer
  page_answers.send(component.name)
end

#valid?Boolean

Returns:

  • (Boolean)


40
41
42
43
44
45
46
47
48
49
# File 'app/validators/metadata_presenter/base_validator.rb', line 40

def valid?
  return true if allow_blank?

  if invalid_answer?
    error_message = custom_error_message || default_error_message
    page_answers.errors.add(component.id, error_message)
  end

  page_answers.errors.blank?
end

#validation_valueObject

The validation configuration value Override if additional formatting of the value is required



134
135
136
# File 'app/validators/metadata_presenter/base_validator.rb', line 134

def validation_value
  component.validation[schema_key]
end