Tram::Validators

Collection of ActiveModel validators for rails projects with focus on composition of standalone policy objects.

Sponsored by Evil Martians

Gem Version Build Status Dependency Status Code Climate

Installation

gem "tram-validators"

Usage

Below is a short review of available validators. Read the specs for more details:

Contract Validator

Checks that a value satisfies a contract, represented by a standalone validator (policy object). It applies policy validator, and collects its messages under corresponding keys.

require "tram-validators" # defines `validity` validator

class SpecificPolicy < SimpleDelegator
  include ActiveModel::Validations
  validates :bar, presence: true
  validates :itself, validity: true # validates wrapped object per se
end

# PolicyObject.new(record.foo).valid? == true
# adds message with i18 translation `foo.contract_specific_policy`
validates :foo, contract: { policy: SpecificPolicy }

# collects messages from policy under their original keys (`bar`)
validates :foo, contract: { policy: PolicyObject, original_keys: true }

# collects messages from policy under nested keys (`foo[bar]`)
validates :foo, contract: { policy: PolicyObject, nested_keys: true }

When you use :nested_keys, the keys :base and :itself will be excluded from chain of nesting. That's why when PolicyObject is invalid at :itself, the last definition will collect error under the key foo, not the foo[itself].

Validity Validator

Checks that an attribute is valid per se. It collects original error messages under corresponding keys.

# record.foo.valid? == true
# adds message with i18 translation `foo.valid`
validates :foo, validity: true

# collects messages from invalid value under their original keys (`bar`)
validates :foo, validity: { original_keys: true }

# collects messages from invalid value under nested keys (`foo[bar]`)
validates :foo, validity: { nested_keys: true }

Each Validator

Applies validation rule to every element of the collection (that responds to to_a).

# Checks that every element of record.list is present
# collects original errors under keys `list[i]` (i for index of invalid item)
validates :list, each: { presence: true }

Outcome Validator

Validates value by checking another method depending on it.

# Validates `user_id` by checking that `user.role` (depending on user_id) is set
# adds error `user_role_presence` to the original attribute  `user_id`
validates :user_id, outcome: { value: "user.role", presence: true }

This technics is useful in form objects where you should attach errors to the original fields accessible to the user.

Consistency Validator

Compares a value of some attribute to a value of another attribute or method chain. Supports all keys from the standard rails numericality validator.

# record.foo < record.bar.baz
# adds error named `less_than_bar_baz` under the key `foo`
validates :foo, consistency: { less_than: "bar.baz" }

Size Validator

Compares size of array to given value or another attribute. Supports all keys from the standard rails numericality validator.

# record.names.size < 6
# adds error named `size_less_than` under the key `names`
validates :names, size: { less_than: 6 }

# record.values.size == record.parent&.names&.size
# adds error named `size_equal_to_parent_names_size` under the key `names`
validates :values, size: { equal_to: "parent.names.size" }

Reference Validator

This is an AR-dependent validator, that checks an instance can be extracted from database by given key.

# Checks that User.find_by(record.user_key).present?
validates :user_key, reference: { model: User, find_by: :key }

Like the outcome validator above, it can be useful for validation of form objects.

License

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