aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael Mendonça França <rafaelmfranca@gmail.com>2015-02-13 12:09:36 -0200
committerRafael Mendonça França <rafaelmfranca@gmail.com>2015-02-13 12:09:36 -0200
commit7919c29d507b571315a6391fe56bf4f3bce23689 (patch)
tree205846ad837a1baacf5572a6fd25e035da1ee050
parentcc08de856acab3f480eb76b3e80cf2ea7705c9b6 (diff)
parentc3fa5c3d25d9148d2806db577a2261032b341c34 (diff)
downloadrails-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.md4
-rw-r--r--activemodel/lib/active_model/validations/length.rb18
-rw-r--r--activemodel/test/cases/validations/length_validation_test.rb13
-rw-r--r--activemodel/test/models/topic.rb4
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