Class: Ward::DSL::ValidationBuilder

Inherits:
Support::BasicObject
Defined in:
lib/ward/dsl/validation_builder.rb

Overview

Creates a single Validator. Any message received which doesn’t correspond with a matcher will be assumed to be part of the context.

Examples:


# Builds a validation whose context is "author.name" and uses the
# EqualTo matcher to ensure that the "author.name" is "Michel Scarn".

ValidationBuilder.new.author.name.is.equal_to('Michael Scarn')

Instance Method Summary collapse

Methods inherited from Support::BasicObject

const_missing

Constructor Details

#initializeValidationBuilder

Creates a new ValidationBuilder instance.



17
18
19
20
# File 'lib/ward/dsl/validation_builder.rb', line 17

def initialize
  @context = Ward::ContextChain.new
  @matcher, @message, @scenarios, @negative = nil, nil, nil, false
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args, &block) ⇒ Ward::DSL::ValidatorBuilder

Provides the DSL.

Will take the given message and use it to customise the matcher (if one is set), set a matcher, or extend the context.

Returns:

  • (Ward::DSL::ValidatorBuilder)

    Returns self.



149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/ward/dsl/validation_builder.rb', line 149

def method_missing(method, *args, &block)
  # I'd normally shy away from using method_missing, but there's no
  # good alternative here since a user may register their own matchers
  # later in the load process.

  if @matcher
    @matcher.__send__(method, *args, &block)
  elsif Ward::Matchers.matchers.has_key?(method)
    @matcher = Ward::Matchers.matchers[method].new(*args, &block)
  elsif method.to_s =~ /\?$/
    @matcher = Ward::Matchers::Predicate.new(method, *args, &block)
  else
    attribute(method, *args, &block)
  end

  self
end

Instance Method Details

#attribute(attribute, *args, &block) ⇒ Ward::DSL::ValidatorBuilder

Adds an attribute to the context chain.

Useful your classes have attribute which you want to validate, and their name conflicts with a method on the validator DSL (e.g. “message”).

Parameters:

  • attribute (Symbol)

    The attribute to be validated.

Returns:

  • (Ward::DSL::ValidatorBuilder)

    Returns self.



108
109
110
111
# File 'lib/ward/dsl/validation_builder.rb', line 108

def attribute(attribute, *args, &block)
  @context << Ward::Context.new(attribute, *args, &block)
  self
end

#context(name) ⇒ Object

Sets the name to be used for the context in error messages.

When Ward generates error messages for you, it determines the ‘context name’ by joining the method names; for example ‘name.length’ becomes ‘name length’.

This isn’t much use if you want to support languages other than English in your application, so the ‘context’ method allows you to set a custom string to be used. You may provide a String, in which case it will be used literally, a Hash of language => String, or a Symbol identifying a string to be used from a language file.

See the localisation documentation for more examples.



76
77
78
79
# File 'lib/ward/dsl/validation_builder.rb', line 76

def context(name)
  @context_name = name
  self
end

#is(*args) ⇒ Ward::DSL::ValidatorBuilder

Set this as a positive expectation. Can be omitted.

Examples:

object.name.is.blank

Returns:

  • (Ward::DSL::ValidatorBuilder)

    Returns self.



121
122
123
124
# File 'lib/ward/dsl/validation_builder.rb', line 121

def is(*args)
  equal_to(*args) unless args.empty?
  self
end

#is_not(*args) ⇒ Ward::DSL::ValidatorBuilder Also known as: does_not

Set this as a negative expectation.

Examples:

object.name.is_not.blank

Returns:

  • (Ward::DSL::ValidatorBuilder)

    Returns self.



134
135
136
137
# File 'lib/ward/dsl/validation_builder.rb', line 134

def is_not(*args)
  @negative = true
  is(*args)
end

#message(message) ⇒ Ward::DSL::ValidatorBuilder

Sets the error message to be used if the validation fails.

This can be one of three possibilities:

* A Hash. If the matcher used returns a different error state in
  order to provide more details about what failed (such as the Has
  matcher), you may provide a hash with custom error messages for
  each error state.

* A String which will be used whenever the validation fails,
  regardless of what went wrong.

* nil (default). The validation will use the default error message
  for the matcher.

Examples:

Setting an explicit error message.


validate do |person|
  person.name.is.present.message('You must enter a name!')
end

Setting an explicit error message with a Hash.


validate do |person|
  person.name.length.is(1..50).message(
    :too_short => "Your name must be at least 1 character long",
    :too_long  => "That's an interesting name!"
  )
end

Parameters:

  • message (Hash{Symbol => String}, String, nil)

Returns:

  • (Ward::DSL::ValidatorBuilder)

    Returns self.



57
58
59
60
# File 'lib/ward/dsl/validation_builder.rb', line 57

def message(message)
  @message = message
  self
end

#scenarios(*scenarios) ⇒ Ward::DSL::ValidatorBuilder Also known as: scenario

Sets the scenarios under which the built validator should run.

Parameters:

  • scenarios (Symbol, ...)

    The scenarios as Symbols.

Returns:

  • (Ward::DSL::ValidatorBuilder)

    Returns self.



89
90
91
92
# File 'lib/ward/dsl/validation_builder.rb', line 89

def scenarios(*scenarios)
  @scenarios = scenarios.flatten
  self
end

#to_validatorWard::Validator

TODO:

More descriptive error messages.

Converts the builder to a Validator instance.

Returns:

Raises:

  • (IncompleteValidation)

    An IncompleteValidationError will be raised if builder does not have all of the needed information in order to create the necessary validation (for example, if no matcher has been set).



179
180
181
182
183
184
185
186
# File 'lib/ward/dsl/validation_builder.rb', line 179

def to_validator
  raise Ward::IncompleteValidator,
    'Validator was missing a matcher' if @matcher.nil?

  Ward::Validator.new(@context, @matcher, :message => @message,
    :scenarios => @scenarios, :negative => @negative,
    :context_name => @context_name)
end