diff options
author | Rafael Mendonça França <rafaelmfranca@gmail.com> | 2015-02-13 12:09:36 -0200 |
---|---|---|
committer | Rafael Mendonça França <rafaelmfranca@gmail.com> | 2015-02-13 12:09:36 -0200 |
commit | 7919c29d507b571315a6391fe56bf4f3bce23689 (patch) | |
tree | 205846ad837a1baacf5572a6fd25e035da1ee050 | |
parent | cc08de856acab3f480eb76b3e80cf2ea7705c9b6 (diff) | |
parent | c3fa5c3d25d9148d2806db577a2261032b341c34 (diff) | |
download | rails-7919c29d507b571315a6391fe56bf4f3bce23689.tar.gz rails-7919c29d507b571315a6391fe56bf4f3bce23689.tar.bz2 rails-7919c29d507b571315a6391fe56bf4f3bce23689.zip |
Merge pull request #16381 from kakipo/validate-length-tokenizer
Allow symbol as values for `tokenizer` of `LengthValidator`
-rw-r--r-- | activemodel/CHANGELOG.md | 4 | ||||
-rw-r--r-- | activemodel/lib/active_model/validations/length.rb | 18 | ||||
-rw-r--r-- | activemodel/test/cases/validations/length_validation_test.rb | 13 | ||||
-rw-r--r-- | activemodel/test/models/topic.rb | 4 |
4 files changed, 32 insertions, 7 deletions
diff --git a/activemodel/CHANGELOG.md b/activemodel/CHANGELOG.md index 5830a00bc5..c303bf5684 100644 --- a/activemodel/CHANGELOG.md +++ b/activemodel/CHANGELOG.md @@ -1,3 +1,7 @@ +* Allow symbol as values for `tokenize` of `LengthValidator` + + *Kensuke Naito* + * Assigning an unknown attribute key to an `ActiveModel` instance during initialization will now raise `ActiveModel::AttributeAssignment::UnknownAttributeError` instead of `NoMethodError` diff --git a/activemodel/lib/active_model/validations/length.rb b/activemodel/lib/active_model/validations/length.rb index a96b30cadd..c63a9d74b3 100644 --- a/activemodel/lib/active_model/validations/length.rb +++ b/activemodel/lib/active_model/validations/length.rb @@ -38,7 +38,7 @@ module ActiveModel end def validate_each(record, attribute, value) - value = tokenize(value) + value = tokenize(record, value) value_length = value.respond_to?(:length) ? value.length : value.to_s.length errors_options = options.except(*RESERVED_OPTIONS) @@ -59,10 +59,14 @@ module ActiveModel end private - - def tokenize(value) - if options[:tokenizer] && value.kind_of?(String) - options[:tokenizer].call(value) + def tokenize(record, value) + tokenizer = options[:tokenizer] + if tokenizer && value.kind_of?(String) + if tokenizer.kind_of?(Proc) + tokenizer.call(value) + elsif record.respond_to?(tokenizer) + record.send(tokenizer, value) + end end || value end @@ -108,8 +112,8 @@ module ActiveModel # * <tt>:message</tt> - The error message to use for a <tt>:minimum</tt>, # <tt>:maximum</tt>, or <tt>:is</tt> violation. An alias of the appropriate # <tt>too_long</tt>/<tt>too_short</tt>/<tt>wrong_length</tt> message. - # * <tt>:tokenizer</tt> - Specifies how to split up the attribute string. - # (e.g. <tt>tokenizer: ->(str) { str.scan(/\w+/) }</tt> to count words + # * <tt>:tokenizer</tt> - Specifies a method, proc or string to how to split up the attribute string. + # (e.g. <tt>tokenizer: ->(str) { str.scan(/\w+/) }</tt> or <tt>tokenizer: :word_tokenizer</tt> to count words # as in above example). Defaults to <tt>->(value) { value.split(//) }</tt> # which counts individual characters. # diff --git a/activemodel/test/cases/validations/length_validation_test.rb b/activemodel/test/cases/validations/length_validation_test.rb index 29130ce46c..209903898e 100644 --- a/activemodel/test/cases/validations/length_validation_test.rb +++ b/activemodel/test/cases/validations/length_validation_test.rb @@ -330,6 +330,19 @@ class LengthValidationTest < ActiveModel::TestCase assert_equal ["Your essay must be at least 5 words."], t.errors[:content] end + + def test_validates_length_of_with_symbol + Topic.validates_length_of :content, minimum: 5, too_short: "Your essay must be at least %{count} words.", + tokenizer: :my_word_tokenizer + t = Topic.new(content: "this content should be long enough") + assert t.valid? + + t.content = "not long enough" + assert t.invalid? + assert t.errors[:content].any? + assert_equal ["Your essay must be at least 5 words."], t.errors[:content] + end + def test_validates_length_of_for_fixnum Topic.validates_length_of(:approved, is: 4) diff --git a/activemodel/test/models/topic.rb b/activemodel/test/models/topic.rb index 1411a093e9..fed50bc361 100644 --- a/activemodel/test/models/topic.rb +++ b/activemodel/test/models/topic.rb @@ -37,4 +37,8 @@ class Topic errors.add attr, "is missing" unless send(attr) end + def my_word_tokenizer(str) + str.scan(/\w+/) + end + end |