The gem basically does three things:
require 'lotus/validations'
class Person
include Lotus::Validations
attribute :name, presence: true
end
person = Person.new(name: 'Luca')
person.name # => "Luca"
person.email # => raises NoMethodError
class Person
include Lotus::Validations
attribute :fave_food, format: /cake/
end
person = Person.new(fave_food: 'tears')
person.valid?
# => false
person = Person.new(fave_food: 'tears')
person.valid?
# => false
person.errors.inspect
# => "#<Lotus::Validations::Errors:0x00000001351140 @errors={
# :fave_food=>[
# #<Lotus::Validations::Error:0x00000001350fd8
# @attribute_name=\"fave_food\",
# @validation=:format,
# @expected=/cake/,
# @actual=\"tears\",
# @namespace=nil,
# @attribute=\"fave_food\">]
# }>"
You can specify a type on your attribute definitions. Assignments will then be coerced, if possible.
class Person
include Lotus::Validations
attribute :fav_number, type: Integer
# Or: Array BigDecimal Boolean Date DateTime
# Float Hash Integer Pathname Set
# String Symbol Time
end
person = Person.new(fav_number: '23')
person.valid?
person.fav_number # => 23
You can define your own coercion classes.
class FavNumber
# The constructor of a class used for type coercion must
# have an arity of one.
def initialize(number)
@number = number
end
end
class Person
include Lotus::Validations
attribute :fav_number, type: FavNumber
end
person = Person.new(fav_number: '23')
person.fav_number # => #<FavNumber:0x007ffc644bba00 @number="23">
Validations are triggered when you invoke #valid?
There are a bunch of them.
attribute :terms_of_service, acceptance: true
An attribute is valid if its value is truthy.
attribute :password, confirmation: true
An attribute is valid if its value and the value of a corresponding attribute is valid.
By convention, if you have a password attribute, the validation looks for password_confirmation.
attribute :pleasant_languages, exclusion: ['c', 'prolog']
Returns false if the attribute value is `#include?`ed in the exclusion list.
attribute :age, inclusion: 18..99
The opposite of exclusion.
attribute :name, format: /\A[a-zA-Z]+\z/
An attribute is valid if it matches the given regex.
attribute :name, presence: true
An attribute is valid if present.
Returns false even if attribute explicitly set to `nil`
“Showing up is 80 percent of life.” - Woody Allen
attribute :ssn, size: 11 # exact match
attribute :password, size: 8..64 # range
An attribute is valid if... uh.
This gem doesn't actually support uniqueness validations.
Any code-level uniqueness test will be subject to race conditions.
“Your relational database is designed to enforce data integrity; let it.”
Unfortunately there's not much to say about this gem.
It's pretty small, does one thing, and seems to do it pretty well.
If I had more time, I would have liked to try defining custom validations.