aboutsummaryrefslogtreecommitdiffstats
path: root/activemodel
diff options
context:
space:
mode:
authorkakipo <kakipo@gmail.com>2014-08-03 14:50:09 +0900
committerkakipo <kakipo@gmail.com>2014-08-03 14:50:09 +0900
commitc3fa5c3d25d9148d2806db577a2261032b341c34 (patch)
tree02db6c7a7a53bc153dd7bf900c551a16bc351403 /activemodel
parentf57cd78a738e1c8cf5a932686e67cd72fdbef301 (diff)
downloadrails-c3fa5c3d25d9148d2806db577a2261032b341c34.tar.gz
rails-c3fa5c3d25d9148d2806db577a2261032b341c34.tar.bz2
rails-c3fa5c3d25d9148d2806db577a2261032b341c34.zip
Allow symbol as values for `tokenize` of `LengthValidator`
Diffstat (limited to 'activemodel')
-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 8d22e3ac46..aa1f3debb5 100644
--- a/activemodel/CHANGELOG.md
+++ b/activemodel/CHANGELOG.md
@@ -1,3 +1,7 @@
+* Allow symbol as values for `tokenize` of `LengthValidator`
+
+ *Kensuke Naito*
+
* Validate options passed to `ActiveModel::Validations.validate`.
Preventing, in many cases, the simple mistake of using `validate` instead of `validates`.
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 046ffcb16f..3fa9f9274c 100644
--- a/activemodel/test/cases/validations/length_validation_test.rb
+++ b/activemodel/test/cases/validations/length_validation_test.rb
@@ -331,6 +331,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