Reference for CQL model validations.
Add validation rules to model fields.
validate field_name, rule: value, ...Field must not be empty/nil.
validate name, presence: trueFails when:
- Value is
nil - String is empty or whitespace only
- Array/Hash is empty
String length constraints.
validate name, length: {min: 2}
validate name, length: {max: 100}
validate name, length: {min: 2, max: 100}
validate code, length: {is: 6}Options:
min : Int32- Minimum lengthmax : Int32- Maximum lengthis : Int32- Exact length
Match regular expression.
validate email, format: {with: /\A[^@\s]+@[^@\s]+\z/}
validate slug, format: {with: /\A[a-z0-9-]+\z/}
validate phone, format: {with: /\A\d{10}\z/}Options:
with : Regex- Pattern to match
Numeric value constraints.
validate age, numericality: {greater_than: 0}
validate age, numericality: {greater_than_or_equal_to: 18}
validate age, numericality: {less_than: 150}
validate age, numericality: {less_than_or_equal_to: 120}
validate quantity, numericality: {equal_to: 1}
validate count, numericality: {other_than: 0}
validate price, numericality: {odd: true}
validate pairs, numericality: {even: true}Options:
greater_than : Numbergreater_than_or_equal_to : Numberless_than : Numberless_than_or_equal_to : Numberequal_to : Numberother_than : Numberodd : Booleven : Bool
Value must be in set.
validate status, inclusion: {in: ["pending", "active", "archived"]}
validate role, inclusion: {in: Role.values.map(&.to_s)}Options:
in : Array- Allowed values
Value must not be in set.
validate username, exclusion: {in: ["admin", "root", "system"]}Options:
in : Array- Forbidden values
Value must be unique in database.
validate email, uniqueness: true
validate slug, uniqueness: {scope: :category_id}
validate code, uniqueness: {case_sensitive: false}Options:
scope : Symbol | Array(Symbol)- Columns to scope uniquenesscase_sensitive : Bool- Case-sensitive comparison (default: true)
Boolean field must be true.
validate terms_accepted, acceptance: trueField must match confirmation field.
validate password, confirmation: true
# Expects password_confirmation fieldSkip validation if value is nil.
validate age, numericality: {greater_than: 0}, allow_nil: trueSkip validation if value is blank.
validate bio, length: {max: 500}, allow_blank: trueRun validation only in specific context.
validate password, presence: true, on: :create
validate password, length: {min: 8}, on: :createValues:
:create- Only on create:update- Only on update:save- On create and update (default)
Conditional validation.
validate phone, presence: true, if: :requires_phone?
validate nickname, presence: true, unless: :has_name?
private def requires_phone?
notification_method == "sms"
endCustom error message.
validate email, presence: {message: "is required for registration"}
validate age, numericality: {greater_than: 0, message: "must be positive"}Override for custom logic.
class Order
include CQL::Model(Order, Int64)
property items : Array(OrderItem)
property total : Float64
def validate
super # Run standard validations
if items.empty?
errors.add(:items, "must have at least one item")
end
if total != items.sum(&.price)
errors.add(:total, "doesn't match item sum")
end
end
endAdd custom error.
errors.add(:field, "message")
errors.add(:base, "general error message")Returns true if all validations pass.
user = User.new(name: "")
user.valid? # => falseReturns true if any validation fails.
user.invalid? # => trueAccess validation errors.
user.errors.each do |error|
puts "#{error.field}: #{error.message}"
end
user.errors.full_messages # => ["Name can't be blank"]
user.errors.on(:name) # => ["can't be blank"]before_validationcallback- Run validations
after_validationcallback- If valid, proceed with save
- If invalid, abort operation
class User
include CQL::Model(User, Int64)
before_validation :normalize_data
private def normalize_data
@email = email.downcase.strip
@name = name.strip
end
endclass User
include CQL::Model(User, Int64)
db_context MyDB, :users
property id : Int64?
property name : String
property email : String
property password_hash : String?
property age : Int32?
property role : String
property terms_accepted : Bool
# Basic validations
validate name, presence: true, length: {min: 2, max: 100}
validate email, presence: true, format: {with: /@/}, uniqueness: true
validate role, inclusion: {in: ["user", "admin", "moderator"]}
validate terms_accepted, acceptance: true, on: :create
# Conditional validation
validate age, numericality: {greater_than: 0, less_than: 150}, allow_nil: true
# Password validation only on create
validate password_hash, presence: true, on: :create
# Custom validation
def validate
super
if role == "admin" && !email.ends_with?("@company.com")
errors.add(:email, "admins must use company email")
end
end
end