Skip to content
mylesmegyesi edited this page Oct 6, 2012 · 18 revisions

Welcome to the metis wiki!

metis

A library for validating maps in Clojure.

Defining a Validator

There are many ways to define a validator. Let's look at all the possible ways.

Single Attribute and Single Validation

no options
(use 'metis.core)

(defvalidator user-validator
    (:first-name :presence))
with options
(defvalidator user-validator
    (:first-name :presence {:message "Please input your first name."}))

Multiple Attributes and Single Validation

no options
(defvalidator user-validator
    ([:first-name :last-name] :presence))
with options
(defvalidator user-validator
    ([:first-name :last-name] :presence {:message "must have a first and last name silly!"}))

Single Attribute and Multiple Validations

no options
(defvalidator user-validator
    (:first-name [:presence :length]))
with options
(defvalidator user-validator
    (:first-name [:presence :length {:equal-to 5}]))

(defvalidator user-validator
    (:first-name [:presence {:message "gotta have it!"} :length]))

(defvalidator user-validator
    (:first-name [:presence {:message "gotta have it!"} :length {:equal-to 5}]))

Multiple Attributes and Multiple Validations

no options
(defvalidator user-validator
    ([:first-name :last-name] [:presence :length]))
with options
(defvalidator user-validator
    ([:first-name :last-name] [:presence :length {:equal-to 5}]))

(defvalidator user-validator
    ([:first-name :last-name] [:presence {:message "gotta have it!"} :length]))

(defvalidator user-validator
    ([:first-name :last-name] [:presence {:message "gotta have it!"} :length {:equal-to 5}]))

As many as you want

(defvalidator user-validator
    ([:address :first-name :last-name :phone-number :email] :presence)
    (:first-name :with {:validator (fn [attr] false) :message "error!"})
    (:last-name :formatted {:pattern #"some pattern" :message "wrong formatting!"}))

(user-validator {:first-name nil :last-name "Smith" :phone-number "123456789" :email "snap.into@slim.jim"}
; {:address ("is not present"), :first-name ("error!" "is not present"), :last-name ("wrong formatting!")}

Contextual Validation

(defvalidator user-validator
    (:first-name :presence {:only :creation :message "error!"})
    (:last-name :formatted {:pattern #"some pattern" :only [:updating :saving] :message "wrong formatting!"})
    (:address :presence {:message "You must have an address." :except [:updating]}))


(user-validator {}) ; when no context is specified, all validations are run
; {:first-name ("error!"), :last-name ("wrong formatting!"), :address ("You must have an address.")}

(user-validator {} :creation)
; {:first-name ("error!"), :address ("You must have an address.")}

(user-validator {} :updating)
; {:last-name ("wrong formatting!")}

(user-validator {} :saving)
; {:last-name ("wrong formatting!"), :address ("You must have an address.")}

(user-validator {} :somewhere-else)
; {:address ("You must have an address.")}

Note: the context names here are arbitrary; they can be anything.

Conditional Validation

(defn payment-type [attrs]                        
  (= (:payment-type attrs) "card"))               
                                                  
(defvalidator :if-conditional                     
  (:card-number :presence {:if payment-type}))    
                                                  
(defvalidator :if-not-conditional                 
  (:card-number :presence {:if-not payment-type}))

(if-conditional {})
; {}

(if-conditional {:payment-type "card"})
; {:card-number ("must be present")}

(if-not-conditional {})
; {:card-number ("must be present")}

(if-not-conditional {:payment-type "card"})
; {}

Shared Options:

These options are shared by all validators, custom or built-in.

  • :message Provide a custom message upon failure.
  • :allow-nil Allow the value to be nil. Default false.
  • :allow-blank Allow the value to be blank (i.e. empty string or empty collection). Default false.
  • :allow-absence Allow the value to be blank or nil. Same as :allow-blank true :allow-nil true. Default false.
  • :only Specifiy the contexts in which the validation should be run. Default [] (all contexts).
  • :except Specifiy the contexts in which the validation should not be run. Default [] (no contexts).
  • :if A function that takes a map and returns true if the validation should be run. Default (fn [attrs] true).
  • :if-not A function that takes map and returns true if the validation should not be run. Default (fn [attrs] false)
Clone this wiki locally