Browse files

including patch by teamon for [#472 state:resolved]

  • Loading branch information...
1 parent d88cfe9 commit 3888768bcec19500fa17c45451a668063473db60 Adam French committed Jul 20, 2008
View
62 dm-validations/lib/dm-validations/auto_validate.rb
@@ -1,6 +1,29 @@
module DataMapper
+ class Property
+ # for options_with_message
+ PROPERTY_OPTIONS << :message << :messages
+ end
+
module Validate
module AutoValidate
+ # adds message for validator
+ def options_with_message(base_options, property, validator_name)
+ options = base_options.clone
+ opts = property.options
+ options[:message] = if opts[:messages]
+ if opts[:messages].is_a?(Hash) and msg = opts[:messages][validator_name]
+ msg
+ else
+ nil
+ end
+ elsif opts[:message]
+ opts[:message]
+ else
+ nil
+ end
+ options
+ end
+
##
# Auto-generate validations for a given property. This will only occur
@@ -33,6 +56,21 @@ module AutoValidate
# Using a Integer type causes a validates_is_number
# validator to be created for the property. integer_only
# is set to false, and precision/scale match the property
+ #
+ #
+ # Messages
+ #
+ # :messages => {..}
+ # Setting :messages hash replaces standard error messages
+ # with custom ones. For instance:
+ # :messages => {:presence => "Field is required",
+ # :format => "Field has invalid format"}
+ # Hash keys are: :presence, :format, :length, :is_unique,
+ # :is_number, :is_primitive
+ #
+ # :message => "Some message"
+ # It is just shortcut if only one validation option is set
+ #
def auto_generate_validations(property)
property.options[:auto_validation] = true unless property.options.has_key?(:auto_validation)
return unless property.options[:auto_validation]
@@ -44,7 +82,8 @@ def auto_generate_validations(property)
# presence
unless opts[:allow_nil]
- validates_present property.name, opts
+ # validates_present property.name, opts
+ validates_present property.name, options_with_message(opts, property, :presence)
end
# length
@@ -56,39 +95,46 @@ def auto_generate_validations(property)
else
opts[:maximum] = len
end
- validates_length property.name, opts
+ # validates_length property.name, opts
+ validates_length property.name, options_with_message(opts, property, :length)
end
# format
if property.options.has_key?(:format)
opts[:with] = property.options[:format]
- validates_format property.name, opts
+ # validates_format property.name, opts
+ validates_format property.name, options_with_message(opts, property, :format)
end
# uniqueness validator
if property.options.has_key?(:unique)
value = property.options[:unique]
if value.is_a?(Array) || value.is_a?(Symbol)
- validates_is_unique property.name, :scope => Array(value)
+ # validates_is_unique property.name, :scope => Array(value)
+ validates_is_unique property.name, options_with_message({:scope => Array(value)}, property, :is_unique)
elsif value.is_a?(TrueClass)
- validates_is_unique property.name
+ # validates_is_unique property.name
+ validates_is_unique property.name, options_with_message({}, property, :is_unique)
end
end
# numeric validator
if Integer == property.type
opts[:integer_only] = true
- validates_is_number property.name, opts
+ # validates_is_number property.name, opts
+ validates_is_number property.name, options_with_message(opts, property, :is_number)
elsif BigDecimal == property.type || Float == property.type
opts[:precision] = property.precision
opts[:scale] = property.scale
- validates_is_number property.name, opts
+ # validates_is_number property.name, opts
+ validates_is_number property.name, options_with_message(opts, property, :is_number)
else
# We only need this in the case we don't already
# have a numeric validator, because otherwise
# it will cause duplicate validation errors
unless property.custom?
- validates_is_primitive property.name, opts
+ # validates_is_primitive property.name, opts
+ validates_is_primitive property.name, options_with_message(opts, property, :is_primitive)
end
end
end
View
49 dm-validations/spec/integration/auto_validate_spec.rb
@@ -259,4 +259,53 @@ class HasNotNullableParanoidBoolean
end
end
end
+
+ describe 'for custom messages' do
+ it "should have correct error message" do
+ custom_boat = Class.new do
+ include DataMapper::Resource
+ property :id, Integer, :serial => true
+ property :name, String, :nullable => false, :message => "This boat must have name"
+ end
+ boat = custom_boat.new
+ boat.should_not be_valid
+
+ boat.errors.on(:name).should eql(["This boat must have name"])
+ end
+
+ it "should have correct error messages" do
+ custom_boat = Class.new do
+ include DataMapper::Resource
+ property :id, Integer, :serial => true
+ property :name, String, :nullable => false, :length => 5..20, :format => /^[a-z]+$/,
+ :messages => {
+ :presence => "This boat must have name",
+ :length => "Name must have at least 4 and at most 20 chars",
+ :format => "Please use only small letters"
+ }
+ end
+
+ boat = custom_boat.new
+ boat.should_not be_valid
+ boat.errors.on(:name).should include("This boat must have name")
+ boat.errors.on(:name).should include("Name must have at least 4 and at most 20 chars")
+ boat.errors.on(:name).should include("Please use only small letters")
+
+ boat.name = "%%"
+ boat.should_not be_valid
+ boat.errors.on(:name).should_not include("This boat must have name")
+ boat.errors.on(:name).should include("Name must have at least 4 and at most 20 chars")
+ boat.errors.on(:name).should include("Please use only small letters")
+
+ boat.name = "%%asd"
+ boat.should_not be_valid
+ boat.errors.on(:name).should_not include("This boat must have name")
+ boat.errors.on(:name).should_not include("Name must have at least 4 and at most 20 chars")
+ boat.errors.on(:name).should include("Please use only small letters")
+
+ boat.name = "superboat"
+ boat.should be_valid
+ boat.errors.on(:name).should be_nil
+ end
+ end
end

0 comments on commit 3888768

Please sign in to comment.