class Check::Validation

Overview

Combines a series of checks into one validation instance, with a customized error message for each case.

A Validation instance provides the means to write sequential checks, fine-tune each micro-validation with their own rules and custom error message, the possibility to retrieve all error messages, etc.

Validation is also used with Check.rules and Check.checkable that provide a powerful and productive system of validation rules which makes data cleaning and data validation in Crystal very easy. With self-generated granular methods for cleaning and checking data.

To use the checker (#check) includes in the Validation class:

require "validator/check"

# Validates the *user* data received in the HTTP controller or other.
def validate_user(user : Hash) : Check::Validation
  v = Check.new_validation

  # -- email

  # Hash key can be a String or a Symbol
  v.check :email, "The email is required.", is :presence?, :email, user

  v.check "email", "The email is required.", is :presence?, "email", user
  v.check "email", "#{user["email"]} is an invalid email.", is :email?, user["email"]

  # -- username

  v.check "username", "The username is required.", is :presence?, "username", user

  v.check(
    "username",
    "The username must contain at least 2 characters.",
    is :min?, user["username"], 2
  )

  v.check(
    "username",
    "The username must contain a maximum of 20 characters.",
    is :max?, user["username"], 20
  )
end

v = validate_user user

pp v.valid? # => true (or false)

# Inverse of v.valid?
if v.errors.empty?
  return "no error"
end

# display all the errors (if any)
pp v.errors

# It's a Hash of Array
errors = v.errors

puts errors.size
puts errors.first_value

errors.each do |key, messages|
  puts key      # => "username"
  puts messages # => ["The username is required.", "etc..."]
end

3 methods #check:

# check(key : Symbol | String, valid : Bool)
# Using default standard error message
v.check(
  "username",
  is(:min?, user["username"], 2)
)

# check(key : Symbol | String, message : String, valid : Bool)
# Using custom error message
v.check(
  "username",
  "The username must contain at least 2 characters.",
  is(:min?, user["username"], 2)
)

# check(key : Symbol | String, valid : Bool, message : String)
# Using custom error message
v.check(
  "username",
  is(:min?, user["username"], 2),
  "The username must contain at least 2 characters."
)

Check is a simple and lightweight wrapper. Check::Validation is agnostic of the checked data, of the context (model, controller, CSV file, HTTP data, socket data, JSON, etc).

Use case example: Before saving to the database or process user data for a particular task, the custom error messages can be used for the end user response.

But a Validation instance can be used just to store validation errors:

v = Check.new_validation
v.add_error("foo", "foo error!")
pp v.errors # => {"foo" => ["foo error!"]}

See also Check.rules and Check.checkable.

Let your imagination run wild to add your logic around it.

Defined in:

check.cr

Constructors

Instance Method Summary

Constructor Detail

def self.new(errors : Errors) #

Initializes a validation using an existing errors Hash (Check::Errors).

v = Check::Validation.new

Same as:

v = Check.new_validation

[View source]
def self.new #

Initializes a validation.

v = Check::Validation.new

Same as:

v = Check.new_validation

[View source]

Instance Method Detail

def add_error(key : Symbol | String, message : String) : Validation #

Add a validation error.

v = Check.new_validation
v.add_error(:foo, "Foo error!")
pp v.errors # => {:foo => ["Foo error!"]}

See also: Errors


[View source]
def add_error(key : Symbol | String) : Validation #

Add a validation error.

By default a standard message is used.

v = Check.new_validation
v.add_error(:foo)
pp v.errors # => {:foo => ["\"foo\" is not valid."]}

See also: Errors


[View source]
def check(key : Symbol | String, message : String, valid : Bool) : Validation #

Checks a validation, often used in sequence.

If valid is false, the error message is added in the #errors. Nothing if valid is true.

v = Check.new_validation

# -- email

v.check :email, "The email is required.", is :presence?, :email, user
v.check :email, "#{user[:email]} is an invalid email.", is :email?, user[:email]?

# -- username

v.check :username, "The username is required.", is :presence?, :username, user

v.check(
  :username,
  "The username must contain at least 2 characters.",
  is :min?, user[:username]?, 2
)

v.check(
  :username,
  "The username must contain a maximum of 20 characters.",
  is :max?, user[:username]?, 20
)

# Print all errors
pp v.errors

[View source]
def check(key : Symbol | String, valid : Bool, message : String) : Validation #

Checks a validation, often used in sequence.

If valid is false, the error message is added in the #errors. Nothing if valid is true.

v = Check.new_validation

# -- email

v.check(:email, is(:presence?, :email, user), "The email is required.")
v.check(:email, is(:email?, user[:email]?), "#{user[:email]} is an invalid email.")

# -- username

v.check(:username, is(:presence?, :username, user), "The username is required.")

v.check(
  :username,
  is :min?, user[:username]?, 2,
    "The username must contain at least 2 characters."
)

v.check(
  :username,
  is :max?, user[:username]?, 20,
    "The username must contain a maximum of 20 characters."
)

# Print all errors
pp v.errors

[View source]
def check(key : Symbol | String, valid : Bool) : Validation #

Checks a validation, often used in sequence.

If valid is false, an error message is added in the #errors. Nothing if valid is true.

Unlike other #check methods, with this one a default standard message is used.

v = Check.new_validation

v.check("email", Valid.presence?("email", user))
v.check("email", Valid.email?(user["email"]?))

# Print all errors
pp v.errors

[View source]
def errors : Errors #

Errors container.

v = Check.new_validation
pp v.errors

[View source]
def to_exception #

Creates a new instance of ValidationError (Exception).


[View source]
def valid? #

Returns true if there is no error, false if there is one or more errors.

pp v.errors if !v.valid?
# or with another flavor ;-)
pp v.errors unless v.valid?

[View source]