Permalink
Browse files

Add validates_not_string validation, useful in conjunction with raise…

…_on_typecast_failure = false

The RDoc gives a good description of the purpose of this:

Validates whether an attribute is not a string.  This is generally
useful in conjunction with raise_on_typecast_failure = false, where
you are passing in string values for non-string attributes (such as
numbers and dates).  If typecasting fails (invalid number or date),
the value of the attribute will be a string in an invalid format, and
if typecasting succeeds, the value will not be a string.
  • Loading branch information...
1 parent 67a1468 commit 5313fc6ecce191d4b0668fe5dafcd296a266360f @jeremyevans committed Jan 26, 2009
Showing with 50 additions and 4 deletions.
  1. +2 −0 CHANGELOG
  2. +28 −0 lib/sequel_model/validations.rb
  3. +20 −4 spec/sequel_model/validations_spec.rb
View
@@ -1,5 +1,7 @@
=== HEAD
+* Add validates_not_string validation, useful in conjunction with raise_on_typecast_failure = false (jeremyevans)
+
* Don't modify Model#new? and Model#changed_columns when saving a record until after the after hooks have been run (tamas, jeremyevans)
* Database#quote_identifiers= now affects future schema modification statements, even if it is not used before one of the schema modification statements (jeremyevans)
@@ -250,6 +250,34 @@ def self.validates_length_of(*atts)
end
end
+ # Validates whether an attribute is not a string. This is generally useful
+ # in conjunction with raise_on_typecast_failure = false, where you are
+ # passing in string values for non-string attributes (such as numbers and dates).
+ # If typecasting fails (invalid number or date), the value of the attribute will
+ # be a string in an invalid format, and if typecasting succeeds, the value will
+ # not be a string.
+ #
+ # Possible Options:
+ # * :message - The message to use (default: 'is a string' or 'is not a valid (integer|datetime|etc.)' if the type is known)
+ def self.validates_not_string(*atts)
+ opts = {
+ :tag => :not_string,
+ }.merge!(atts.extract_options!)
+ atts << opts
+ validates_each(*atts) do |o, a, v|
+ if v.is_a?(String)
+ unless message = opts[:message]
+ message = if sch = o.db_schema[a] and typ = sch[:type]
+ "is not a valid #{typ}"
+ else
+ "is a string"
+ end
+ end
+ o.errors[a] << message
+ end
+ end
+ end
+
# Validates whether an attribute is a number.
#
# Possible Options:
@@ -715,10 +715,6 @@ class ::Person < Sequel::Model
@person.valid?.should be_true
end
- # it "should allow for :with_exactly => /[a-zA-Z]/, which wraps the supplied regex with ^<regex>$" do
- # pending("TODO: Add this option to Validatable#validates_format_of")
- # end
-
it "should validate length of column" do
class ::Person < Sequel::Model
validations.clear
@@ -751,6 +747,26 @@ class ::Person < Sequel::Model
@person.should be_valid
end
+ it "should validate that a column doesn't have a string value" do
+ p = Class.new(Sequel::Model)
+ p.class_eval do
+ columns :age
+ self.raise_on_typecast_failure = false
+ validates_not_string :age
+ @db_schema = {:age=>{:type=>:integer}}
+ end
+
+ @person = p.new :age => "a"
+ @person.should_not be_valid
+ @person.errors.full_messages.should == ['age is not a valid integer']
+ @person.db_schema[:age][:type] = :datetime
+ @person.should_not be_valid
+ @person.errors.full_messages.should == ['age is not a valid datetime']
+
+ @person.age = 20
+ @person.should be_valid
+ end
+
it "should validate numericality of column" do
class ::Person < Sequel::Model
validations.clear

0 comments on commit 5313fc6

Please sign in to comment.