0.0
No commit activity in last 3 years
No release in over 3 years
Object validation library
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

~> 1.3
>= 0
>= 0

Runtime

>= 0
 Project Readme

PureValidator

Build Status Gem Version Code Climate codecov Dependency Status

PureValidator is a simple, mostly dependency-free (except i18n) library to validate your domain Ruby objects.

It keeps the concerns of validation separate from the Entity / Value object itself.

This gives you the option to have different validations rules for different ocasions for the same object in a very clean and unit-testable way.

It is a simple step to separate those concerns, but it will give you unlimited flexibility and save your *SS from debugging entangled and conflicting validations for non-trivial requirements.

Do yourself a favor and start using PureValidator today, you will never look back!

Installation

Add this line to your application's Gemfile:

gem 'pure_validator'

Usage

Let's say you have the following class and you want to validate its instances:

class Contact
  attr_accessor :first_name, :last_name, :position, :age, :type,
    :email, :color, :status, :stage, :description,
    :companies, :address

  def to_h
    {
      first_name: first_name,
      last_name: last_name,
      position: position,
      age: age,
      type: type,
      email: email,
      color: color,
      status: status,
      stage: stage,
      description: description,
      companies: (companies||[]).map(&:to_h),
      address: (address && address.to_h),
    }
  end
end

To validate objects of the Contact class define following validator:

class ContactValidator
  include PureValidator::Validator

  validates :first_name, presence: true, length: { min: 4, max: 7 }
  validates :last_name,  length: { equal_to: 5 }
  validates :position,   length: { not_equal_to: 5 }
  validates :age,        numericality: { greater_than: 0, less_than: 150 }
  validates :type,       numericality: { greater_than_or_equal_to: 1, less_than_or_equal_to: 5 }
  validates :email,      email: true
  validates :color,      regexp: /#\w{6}/
  validates :status,     inclusion: { in: [:new, :lead] }
  validates :stage,      exclusion: { in: [:wrong, :bad] }

  validate_associated :companies, validator: CompanyValidator

  validate :check_description

  def check_description(entity, errors)
    if entity.description.nil?
      errors.add(:description, "can't be empty")
    end
  end
end

Instantiate the validator and call validate with a contact object:

errors = ContactValidator.new.validate(contact)

It also works with plain hashes:

errors = ContactValidator.new.validate(contact.to_h)

errors is a Hash that contains all validation errors. If the object is valid then errors will be an empty Hash.

Adding own validators

PureValidator can be extended by adding your own validators. To add a validator define a class with 2 static methods: validate and validate_options:

The following example shows the built-in inclusion validator, it validates that specified value is one of the defined values.

class PureValidator::Validators::InclusionValidator

  # Validates that given value inscluded in the specified list
  # @param value [Object] object to validate
  # @parm options [Hash] validation options, e.g. { in: [:small, :medium, :large], message: "not included in the list of allowed items" }
  #                      where :in - list of allowed values,
  #                      message - is a message to return if value is not included in the list
  # @return [Array] empty array if object is valid, list of errors otherwise
  def self.validate(value, options)
    return [] if value.nil?

    errors = []
    if options[:in]
      unless options[:in].include?(value)
        errors << (options[:message] || PureValidator::I18n.t('errors.should_be_included_in_list', list: options[:in]))
      end
    end
    errors
  end

  # Validates that options specified in
  # :inclusion are valid
  def self.validate_options(options)
    raise ArgumentError, "validation options should be a Hash" unless options.is_a?(Hash)
    raise ArgumentError, "validation options should have :in option and it should be an array of allowed values" unless options[:in].is_a?(Array)
  end

end

And register it in PureValidator:

PureValidator.add_validator(:inclusion, PureValidator::Validators::InclusionValidator)

Now you can use it:

class SomeValidator
  include PureValidator::Validator

  validates :size, inclusion: { in: [:small, :medium, :large] }
end

Installation

Add this line to your application's Gemfile:

gem 'pure_validator'

And then execute:

$ bundle

Or install it yourself as:

$ gem install pure_validator

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request

Authors