public
Description: Ruby on Rails
Homepage: http://rubyonrails.org
Clone URL: git://github.com/rails/rails.git
Add :tokenizer option to validates_length_of. [#507 state:resolved]

Signed-off-by: Pratik Naik <pratiknaik@gmail.com>
dfl (author)
Sat Jun 28 17:41:12 -0700 2008
lifo (committer)
Thu Jul 03 17:31:39 -0700 2008
commit  87fbcaa6229e9073095fb8d77c7a536c9466fbce
tree    93ad434fdfc2be549da65ad4d167b5d9c4859802
parent  570f5aad663fa3113772cf56306862829babc739
...
1
2
 
 
 
 
 
3
4
5
...
1
2
3
4
5
6
7
8
9
10
0
@@ -1,5 +1,10 @@
0
 *Edge*
0
 
0
+* Add :tokenizer option to validates_length_of to specify how to split up the attribute string. #507. [David Lowenfels] Example :
0
+
0
+ # Ensure essay contains at least 100 words.
0
+ validates_length_of :essay, :minimum => 100, :too_short => "Your essay must be at least %d words."), :tokenizer => lambda {|str| str.scan(/\w+/) }
0
+
0
 * Allow conditions on multiple tables to be specified using hash. [Pratik Naik]. Example:
0
 
0
   User.all :joins => :items, :conditions => { :age => 10, :items => { :color => 'black' } }
...
479
480
481
482
483
 
 
 
484
485
486
...
491
492
493
494
495
496
497
...
503
504
505
 
 
 
506
507
508
509
510
511
 
 
512
513
514
...
535
536
537
538
 
539
540
541
...
552
553
554
555
 
556
557
558
...
479
480
481
 
 
482
483
484
485
486
487
...
492
493
494
 
495
496
497
...
503
504
505
506
507
508
509
510
511
512
513
 
514
515
516
517
518
...
539
540
541
 
542
543
544
545
...
556
557
558
 
559
560
561
562
0
@@ -479,8 +479,9 @@ module ActiveRecord
0
       # validates_length_of :fax, :in => 7..32, :allow_nil => true
0
       # validates_length_of :phone, :in => 7..32, :allow_blank => true
0
       # validates_length_of :user_name, :within => 6..20, :too_long => "pick a shorter name", :too_short => "pick a longer name"
0
- # validates_length_of :fav_bra_size, :minimum=>1, :too_short=>"please enter at least %d character"
0
- # validates_length_of :smurf_leader, :is=>4, :message=>"papa is spelled with %d characters... don't play me."
0
+ # validates_length_of :fav_bra_size, :minimum => 1, :too_short => "please enter at least %d character"
0
+ # validates_length_of :smurf_leader, :is => 4, :message => "papa is spelled with %d characters... don't play me."
0
+ # validates_length_of :essay, :minimum => 100, :too_short => "Your essay must be at least %d words."), :tokenizer => lambda {|str| str.scan(/\w+/) }
0
       # end
0
       #
0
       # Configuration options:
0
@@ -491,7 +492,6 @@ module ActiveRecord
0
       # * <tt>:in</tt> - A synonym(or alias) for <tt>:within</tt>.
0
       # * <tt>:allow_nil</tt> - Attribute may be +nil+; skip validation.
0
       # * <tt>:allow_blank</tt> - Attribute may be blank; skip validation.
0
- #
0
       # * <tt>:too_long</tt> - The error message if the attribute goes over the maximum (default is: "is too long (maximum is %d characters)").
0
       # * <tt>:too_short</tt> - The error message if the attribute goes under the minimum (default is: "is too short (min is %d characters)").
0
       # * <tt>:wrong_length</tt> - The error message if using the <tt>:is</tt> method and the attribute is the wrong size (default is: "is the wrong length (should be %d characters)").
0
@@ -503,12 +503,16 @@ module ActiveRecord
0
       # * <tt>:unless</tt> - Specifies a method, proc or string to call to determine if the validation should
0
       # not occur (e.g. <tt>:unless => :skip_validation</tt>, or <tt>:unless => Proc.new { |user| user.signup_step <= 2 }</tt>). The
0
       # method, proc or string should return or evaluate to a true or false value.
0
+ # * <tt>:tokenizer</tt> - Specifies how to split up the attribute string. (e.g. <tt>:tokenizer => lambda {|str| str.scan(/\w+/)}</tt> to
0
+ # count words as in above example.)
0
+ # Defaults to <tt>lambda{ |value| value.split(//) }</tt> which counts individual characters.
0
       def validates_length_of(*attrs)
0
         # Merge given options with defaults.
0
         options = {
0
           :too_long => ActiveRecord::Errors.default_error_messages[:too_long],
0
           :too_short => ActiveRecord::Errors.default_error_messages[:too_short],
0
- :wrong_length => ActiveRecord::Errors.default_error_messages[:wrong_length]
0
+ :wrong_length => ActiveRecord::Errors.default_error_messages[:wrong_length],
0
+ :tokenizer => lambda {|value| value.split(//)}
0
         }.merge(DEFAULT_VALIDATION_OPTIONS)
0
         options.update(attrs.extract_options!.symbolize_keys)
0
 
0
@@ -535,7 +539,7 @@ module ActiveRecord
0
             too_long = options[:too_long] % option_value.end
0
 
0
             validates_each(attrs, options) do |record, attr, value|
0
- value = value.split(//) if value.kind_of?(String)
0
+ value = options[:tokenizer].call(value) if value.kind_of?(String)
0
               if value.nil? or value.size < option_value.begin
0
                 record.errors.add(attr, too_short)
0
               elsif value.size > option_value.end
0
@@ -552,7 +556,7 @@ module ActiveRecord
0
             message = (options[:message] || options[message_options[option]]) % option_value
0
 
0
             validates_each(attrs, options) do |record, attr, value|
0
- value = value.split(//) if value.kind_of?(String)
0
+ value = options[:tokenizer].call(value) if value.kind_of?(String)
0
               record.errors.add(attr, message) unless !value.nil? and value.size.method(validity_checks[option])[option_value]
0
             end
0
         end
...
1059
1060
1061
 
 
 
 
 
 
 
 
 
 
 
 
1062
1063
1064
...
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
0
@@ -1059,6 +1059,18 @@ class ValidationsTest < ActiveRecord::TestCase
0
     end
0
   end
0
 
0
+ def test_validates_length_of_with_block
0
+ Topic.validates_length_of :content, :minimum => 5, :too_short=>"Your essay must be at least %d words.",
0
+ :tokenizer => lambda {|str| str.scan(/\w+/) }
0
+ t = Topic.create!(:content => "this content should be long enough")
0
+ assert t.valid?
0
+
0
+ t.content = "not long enough"
0
+ assert !t.valid?
0
+ assert t.errors.on(:content)
0
+ assert_equal "Your essay must be at least 5 words.", t.errors[:content]
0
+ end
0
+
0
   def test_validates_size_of_association_utf8
0
     with_kcode('UTF8') do
0
       assert_nothing_raised { Topic.validates_size_of :replies, :minimum => 1 }

Comments

    No one has commented yet.