Implemented strict validation concept
In order to deliver debug information to dev team instead of display error message to end user Implemented strict validation concept that suppose to define validation that always raise exception when fails
This commit is contained in:
parent
5912f3f97e
commit
8620bf90c5
@ -63,7 +63,7 @@ module ActiveModel
|
||||
class Errors
|
||||
include Enumerable
|
||||
|
||||
CALLBACKS_OPTIONS = [:if, :unless, :on, :allow_nil, :allow_blank]
|
||||
CALLBACKS_OPTIONS = [:if, :unless, :on, :allow_nil, :allow_blank, :strict]
|
||||
|
||||
attr_reader :messages
|
||||
|
||||
@ -218,6 +218,9 @@ def add(attribute, message = nil, options = {})
|
||||
elsif message.is_a?(Proc)
|
||||
message = message.call
|
||||
end
|
||||
if options[:strict]
|
||||
raise ActiveModel::StrictValidationFailed, message
|
||||
end
|
||||
|
||||
self[attribute] << message
|
||||
end
|
||||
@ -319,4 +322,7 @@ def generate_message(attribute, type = :invalid, options = {})
|
||||
I18n.translate(key, options)
|
||||
end
|
||||
end
|
||||
|
||||
class StrictValidationFailed < StandardError
|
||||
end
|
||||
end
|
||||
|
@ -58,6 +58,8 @@ module HelperMethods
|
||||
# <tt>:unless => Proc.new { |user| user.signup_step <= 2 }</tt>).
|
||||
# The method, proc or string should return or evaluate to a true or
|
||||
# false value.
|
||||
# * <tt>:strict</tt> - Specifies whether validation should be strict.
|
||||
# See <tt>ActiveModel::Validation#validates!</tt> for more information
|
||||
def validates_acceptance_of(*attr_names)
|
||||
validates_with AcceptanceValidator, _merge_attributes(attr_names)
|
||||
end
|
||||
|
@ -58,6 +58,8 @@ module HelperMethods
|
||||
# <tt>:unless => :skip_validation</tt>, or
|
||||
# <tt>:unless => Proc.new { |user| user.signup_step <= 2 }</tt>). The
|
||||
# method, proc or string should return or evaluate to a true or false value.
|
||||
# * <tt>:strict</tt> - Specifies whether validation should be strict.
|
||||
# See <tt>ActiveModel::Validation#validates!</tt> for more information
|
||||
def validates_confirmation_of(*attr_names)
|
||||
validates_with ConfirmationValidator, _merge_attributes(attr_names)
|
||||
end
|
||||
|
@ -59,6 +59,8 @@ module HelperMethods
|
||||
# * <tt>:unless</tt> - Specifies a method, proc or string to call to determine if the validation should
|
||||
# not occur (e.g. <tt>:unless => :skip_validation</tt>, or <tt>:unless => Proc.new { |user| user.signup_step <= 2 }</tt>). The
|
||||
# method, proc or string should return or evaluate to a true or false value.
|
||||
# * <tt>:strict</tt> - Specifies whether validation should be strict.
|
||||
# See <tt>ActiveModel::Validation#validates!</tt> for more information
|
||||
def validates_exclusion_of(*attr_names)
|
||||
validates_with ExclusionValidator, _merge_attributes(attr_names)
|
||||
end
|
||||
|
@ -84,6 +84,8 @@ module HelperMethods
|
||||
# * <tt>:unless</tt> - Specifies a method, proc or string to call to determine if the validation should
|
||||
# not occur (e.g. <tt>:unless => :skip_validation</tt>, or <tt>:unless => Proc.new { |user| user.signup_step <= 2 }</tt>). The
|
||||
# method, proc or string should return or evaluate to a true or false value.
|
||||
# * <tt>:strict</tt> - Specifies whether validation should be strict.
|
||||
# See <tt>ActiveModel::Validation#validates!</tt> for more information
|
||||
def validates_format_of(*attr_names)
|
||||
validates_with FormatValidator, _merge_attributes(attr_names)
|
||||
end
|
||||
|
@ -59,6 +59,8 @@ module HelperMethods
|
||||
# * <tt>:unless</tt> - Specifies a method, proc or string to call to determine if the validation should
|
||||
# not occur (e.g. <tt>:unless => :skip_validation</tt>, or <tt>:unless => Proc.new { |user| user.signup_step <= 2 }</tt>). The
|
||||
# method, proc or string should return or evaluate to a true or false value.
|
||||
# * <tt>:strict</tt> - Specifies whether validation should be strict.
|
||||
# See <tt>ActiveModel::Validation#validates!</tt> for more information
|
||||
def validates_inclusion_of(*attr_names)
|
||||
validates_with InclusionValidator, _merge_attributes(attr_names)
|
||||
end
|
||||
|
@ -96,6 +96,8 @@ module HelperMethods
|
||||
# * <tt>:tokenizer</tt> - Specifies how to split up the attribute string. (e.g. <tt>:tokenizer => lambda {|str| str.scan(/\w+/)}</tt> to
|
||||
# count words as in above example.)
|
||||
# Defaults to <tt>lambda{ |value| value.split(//) }</tt> which counts individual characters.
|
||||
# * <tt>:strict</tt> - Specifies whether validation should be strict.
|
||||
# See <tt>ActiveModel::Validation#validates!</tt> for more information
|
||||
def validates_length_of(*attr_names)
|
||||
validates_with LengthValidator, _merge_attributes(attr_names)
|
||||
end
|
||||
|
@ -107,6 +107,8 @@ module HelperMethods
|
||||
# * <tt>:unless</tt> - Specifies a method, proc or string to call to determine if the validation should
|
||||
# not occur (e.g. <tt>:unless => :skip_validation</tt>, or <tt>:unless => Proc.new { |user| user.signup_step <= 2 }</tt>). The
|
||||
# method, proc or string should return or evaluate to a true or false value.
|
||||
# * <tt>:strict</tt> - Specifies whether validation should be strict.
|
||||
# See <tt>ActiveModel::Validation#validates!</tt> for more information
|
||||
#
|
||||
# The following checks can also be supplied with a proc or a symbol which corresponds to a method:
|
||||
# * <tt>:greater_than</tt>
|
||||
|
@ -35,6 +35,8 @@ module HelperMethods
|
||||
# * <tt>unless</tt> - Specifies a method, proc or string to call to determine if the validation should
|
||||
# not occur (e.g. <tt>:unless => :skip_validation</tt>, or <tt>:unless => Proc.new { |user| user.signup_step <= 2 }</tt>).
|
||||
# The method, proc or string should return or evaluate to a true or false value.
|
||||
# * <tt>:strict</tt> - Specifies whether validation should be strict.
|
||||
# See <tt>ActiveModel::Validation#validates!</tt> for more information
|
||||
#
|
||||
def validates_presence_of(*attr_names)
|
||||
validates_with PresenceValidator, _merge_attributes(attr_names)
|
||||
|
@ -70,8 +70,8 @@ module ClassMethods
|
||||
# validator's initializer as +options[:in]+ while other types including
|
||||
# regular expressions and strings are passed as +options[:with]+
|
||||
#
|
||||
# Finally, the options +:if+, +:unless+, +:on+, +:allow_blank+ and +:allow_nil+ can be given
|
||||
# to one specific validator, as a hash:
|
||||
# Finally, the options +:if+, +:unless+, +:on+, +:allow_blank+, +:allow_nil+ and +:strict+
|
||||
# can be given to one specific validator, as a hash:
|
||||
#
|
||||
# validates :password, :presence => { :if => :password_required? }, :confirmation => true
|
||||
#
|
||||
@ -101,12 +101,24 @@ def validates(*attributes)
|
||||
end
|
||||
end
|
||||
|
||||
# This method is used to define validation that can not be correcterized by end user
|
||||
# and is considered exceptional.
|
||||
# So each validator defined with bang or <tt>:strict</tt> option set to <tt>true</tt>
|
||||
# will always raise <tt>ActiveModel::InternalValidationFailed</tt> instead of adding error
|
||||
# when validation fails
|
||||
# See <tt>validates</tt> for more information about validation itself.
|
||||
def validates!(*attributes)
|
||||
options = attributes.extract_options!
|
||||
options[:strict] = true
|
||||
validates(*(attributes << options))
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
# When creating custom validators, it might be useful to be able to specify
|
||||
# additional default keys. This can be done by overwriting this method.
|
||||
def _validates_default_keys
|
||||
[ :if, :unless, :on, :allow_blank, :allow_nil ]
|
||||
[ :if, :unless, :on, :allow_blank, :allow_nil , :strict]
|
||||
end
|
||||
|
||||
def _parse_validates_options(options) #:nodoc:
|
||||
|
@ -61,7 +61,9 @@ module ClassMethods
|
||||
# (e.g. <tt>:unless => :skip_validation</tt>, or
|
||||
# <tt>:unless => Proc.new { |user| user.signup_step <= 2 }</tt>).
|
||||
# The method, proc or string should return or evaluate to a true or false value.
|
||||
#
|
||||
# * <tt>:strict</tt> - Specifies whether validation should be strict.
|
||||
# See <tt>ActiveModel::Validation#validates!</tt> for more information
|
||||
|
||||
# If you pass any additional configuration options, they will be passed
|
||||
# to the class and available as <tt>options</tt>:
|
||||
#
|
||||
@ -140,4 +142,4 @@ def validates_with(*args, &block)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -297,4 +297,37 @@ def test_validations_on_the_instance_level
|
||||
|
||||
assert auto.valid?
|
||||
end
|
||||
|
||||
def test_strict_validation_in_validates
|
||||
Topic.validates :title, :strict => true, :presence => true
|
||||
assert_raises ActiveModel::StrictValidationFailed do
|
||||
Topic.new.valid?
|
||||
end
|
||||
end
|
||||
|
||||
def test_strict_validation_not_fails
|
||||
Topic.validates :title, :strict => true, :presence => true
|
||||
assert Topic.new(:title => "hello").valid?
|
||||
end
|
||||
|
||||
def test_strict_validation_particular_validator
|
||||
Topic.validates :title, :presence => {:strict => true}
|
||||
assert_raises ActiveModel::StrictValidationFailed do
|
||||
Topic.new.valid?
|
||||
end
|
||||
end
|
||||
|
||||
def test_strict_validation_in_custom_validator_helper
|
||||
Topic.validates_presence_of :title, :strict => true
|
||||
assert_raises ActiveModel::StrictValidationFailed do
|
||||
Topic.new.valid?
|
||||
end
|
||||
end
|
||||
|
||||
def test_validates_with_bang
|
||||
Topic.validates! :title, :presence => true
|
||||
assert_raises ActiveModel::StrictValidationFailed do
|
||||
Topic.new.valid?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user