ValidationProfiler

Welcome to ValidationProfiler. This is a validation framework that allows you to seperate validation logic away from your objects and into validation profiles that can be re-used and changed without affecting your objects.

Installation

Add this line to your application's Gemfile:

gem 'validation_profiler'

And then execute:

$ bundle

Or install it yourself as:

$ gem install validation_profiler

Usage

First you need to create a validation profile to hold the validation logic you want to apply, validation profiles must inherit from the ValidationProfile base class or another validation profile.

class SignUpValidationProfile < ValidationProfile
    .....
end

Then you specify validation rules that should be checked when this profile is validated against an object.

class SignUpValidationProfile < ValidationProfile
    validates :age, :min, { value: 18 }
    validates :email, :email
    ..... 
end

When specifying a validation rule you need to specify the following arguments:

  • Field name
  • Rule key
  • Hash containing any options required for the validation rule

So if we take another look at the first validation rule we specified in the SignUpValidationProfile above:

Field name = :age
Rule key = :min 
Attributes Hash = { value: 18 }

This validation statement will be interpreted as: "The field :age must have a minimum value of 18"

To use a validation profile you need to make a call to the ValidationManager class, and pass the object you want to validate along with the profile you want to use for the validation:

#create the validation manager
manager = ValidationManager.new

#call the validate method and pass the object and profile
result = manager.validate(user, profile)

Calls to the validate method will return a ValidationManagerResult that will detail the results of the validation.

A ValidationManagerResult has the following attributes:

  • #outcome = [Boolean] overall outcome of the validation (passed or failed)
  • #errors = [Array] containing details of each field error that occurred during validation.

Each item in the errors array has the following attributes:

  • #field = The name of the field that this error occurred for.
  • #message = A message that describes the validation error

Validation Rules

RequiredValidationRule

This rule is used to specify a field must contain a value:

validates :name, :required

Attributes:

  • :message [String] [Optional] This is used to allow a custom error message to be specified.

LengthValidationRule

This rule is used to specify a [String] or [Array] must be of a certain length:

validates :name, :length, { min: 5, max: 10 }

Attributes:

  • :min [Numeric] This is used to specify the minimum length of the field value.

  • :max [Numeric] This is used to specify the maximum length of the field value.

:min & :max can be included together or independently providing at least 1 is specified.

  • :message [String] [Optional] This is used to allow a custom error message to be specified.

  • :required [Boolean] [Default=True] [Optional] This is used to specify if this rule should only be executed when the field contains a value.

    True always executes, False only executes when the field contains a value)*


MinValidationRule

This rule is used to specify a minimum value a [DateTime] or [Numeric] field must have.

Attributes:

  • :value [Numeric/DateTime] This is used to specify the minimum value of the field.

  • :message [String] [Optional] This is used to allow a custom error message to be specified.

  • :required [Boolean] [Default=True] [Optional] This is used to specify if this rule should only be executed when the field contains a value.

    True always executes, False only executes when the field contains a value)*


MaxValidationRule

This rule is used to specify a maximum value a [DateTime] or [Numeric] field must have.

Attributes:

  • :value [Numeric/DateTime] This is used to specify the maximum value of the field.

  • :message [String] [Optional] This is used to allow a custom error message to be specified.

  • :required [Boolean] [Default=True] [Optional] This is used to specify if this rule should only be executed the field contains a value.

    True always executes, False only executes when the field contains a value)*


EmailValidationRule

This rule is used to specify a field value must contain a valid email address.

Attributes:

  • :message [String] [Optional] This is used to allow a custom error message to be specified.

  • :required [Boolean] [Default=True] [Optional] This is used to specify if this rule should only be executed when the field contains a value.

    True always executes, False only executes when the field contains a value)*


RegexValidationRule

This rule is used to specify a regex pattern that a field value must validate against.

Attributes:

  • :regex [Regex] This is used to specify the regex pattern.

  • :message [String] [Optional] This is used to allow a custom error message to be specified.

  • :required [Boolean] [Default=True] [Optional] This is used to specify if this rule should only be executed when the field contains a value.

    True always executes, False only executes when the field contains a value)*


MatchValidationRule

This rule is used to specify a field value must match the value of another field.

Attributes:

  • :field [Symbol] This is used to specify the name of the other field this field's value must match.

  • :message [String] [Optional] This is used to allow a custom error message to be specified.

  • :required [Boolean] [Default=True] [Optional] This is used to specify if this rule should only be executed when the field contains a value.

    True always executes, False only executes when the field contains a value)


ConditionValidationRule

This rule is used to specify a condition statement.

e.g.

format:

When [:condition_field] [:condition_expression] [:condition_value] then [:field] [:field_expression] [:field_value]

could be read as:

When :age >= 18 then :accept == true

Attributes:

  • :condition_field [Symbol] This is used to specify the name of the condition field.

  • :condition_expression [String] This is used to specify the expression to use between the condition_field and the condition_value.

Supported expression types: '==' '>' '>=' '<' '<=' '!='

  • :condition_value [String/Numeric/DateTime/nil] This is used to specify the value to use for the condition statement.

  • :field_expression [String] This is used to specify the expression to use between the field's value and the field_value attribute.

  • :field_value [String/Numeric/DateTime/nil] This is used to specify the value to use for the field statement.

  • :message [String] [Optional] This is used to allow a custom error message to be specified.

  • :required [Boolean] [Default=True] [Optional] This is used to specify if this rule should only be executed when the field contains a value.

    True always executes, False only executes when the field contains a value)


Custom Validation Rules

To create a custom validation rule you must create a class that inherits from the ValidationRule base class and implement the #error_message and #validate methods, see the RequiredValidationRule below as an example:

class RequiredValidationRule < ValidationRule
    #implement this method to return the error message when
    #this rule fails validation
    def error_message(field, attributes = {})
        #check if custom message was specified
        if attributes[:message] == nil
            #return default method
          "#{field} is not valid"
        else
            #return custom message
          attributes[:message]
        end
    end

    def validate(obj, field, attributes = {})
        #attempt to get the field value from the object
        field_value = get_field_value(obj, field)

        if field_value == nil
          return false
        end

        return !field_value.empty?
    end
end

The ValidationRule base class provides the #get_field_value(obj, field) method to cater for fetching the field value from the object to perform the validation against.

Development

After checking out the repo, run bin/setup to install dependencies. You can also run bin/console for an interactive prompt that will allow you to experiment.

To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and tags, and push the .gem file to rubygems.org.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/vaughanbrittonsage/validation_profiler. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.

License

The gem is available as open source under the terms of the MIT License.