module Check
Overview
Standalone check module that provides a practical workflow for validations.
Defined in:
check.crcheckable.cr
Constant Summary
-
RULES =
{} of String => HashLiteral(String, ASTNode)
Class Method Summary
-
.new_validation(errors : Errors)
Initializes a new
Validation
instance to combine a series of checks (Validation#check
). -
.new_validation
Initializes a new
Validation
instance to combine a series of checks (Validation#check
).
Macro Summary
-
checkable
A mixin to make a class checkable.
-
rules(**fields)
Generates
check
,check_{{field}}
andclean_{{field}}
methods for fields (class variables).
Class Method Detail
Initializes a new Validation
instance to combine
a series of checks (Validation#check
).
using an existing errors Hash
(Check::Errors
).
v = Check.new_validation existing_errors
Same as:
v = Check::Validation.new existing_errors
Example to combine two hashes of validation errors:
preview_validation = Check.new_validation
v = Check.new_validation preview_validation.errors
Initializes a new Validation
instance to combine
a series of checks (Validation#check
).
v = Check.new_validation
Same as:
v = Check::Validation.new
Macro Detail
A mixin to make a class checkable.
This mixin includes Checkable
and CheckableStatic
.
It must be used in conjonction with Check.rules
.
require "validator/check"
class Article
# Mixin
Check.checkable
property title : String
property content : String, {
required: true,
check: {
not_empty: {"Article content is required"},
between: {"The article content must be between 10 and 20 000 characters", 10, 20_000},
# ...
},
clean: {
type: String,
to: :to_s,
format: ->(content : String) { content.strip },
message: "Wrong type",
},
}
def initialize(@title, @content)
end
end
# Triggered on all data
v, article = Article.check(input_data)
# Triggered on a value
v, content = Article.check_content(input_data["content"]?)
Generates check
, check_{{field}}
and clean_{{field}}
methods for fields (class variables).
require "validator/check"
class Article
# Mixin
Check.checkable
property title : String
property content : String
property url : String?
private def self.after_check_content(v : Check::Validation, content : String?, required : Bool, format : Bool)
puts "after_check_content"
puts "Valid? #{v.valid?}"
content
end
Check.rules(
content: {
required: "Content is required", # or `true` to use the default error message
before_check: ->(v : Check::Validation, content : String?, required : Bool, format : Bool) {
puts "before_check_content"
content
},
after_check: :after_check_email,
check: {
not_empty: {"Article content is required"},
between: {"The article content must be between 10 and 20 000 characters", 10, 20_000},
# ...
},
clean: {
type: String,
to: :to_s,
# Proc or method name (Symbol)
format: ->(content : String) { content.strip },
message: "Wrong type",
},
},
url: {
check: {
url: {"Article URL is invalid"},
},
clean: {
# `nilable` means omited if not provided,
# regardless of Crystal type (nilable or not)
nilable: true,
# Crystal type
type: String,
# Converter to the expected typed value
to: :to_s,
},
},
# ...
)
end
# Triggered on all data
v, article = Article.check(input_data)
# Triggered on all fields of an instance
article = Article.new(title: "foo", content: "bar")
v = article.check
# Triggered on a value
v, content = Article.check_content(input_data["content"]?)
# Cast and clean a value
ok, content = Article.clean_content(input_data["content"]?)
See also Check.checkable
.