Allow symbol as values for tokenize
of LengthValidator
This commit is contained in:
parent
f57cd78a73
commit
c3fa5c3d25
@ -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`.
|
||||
|
@ -38,7 +38,7 @@ def check_validity!
|
||||
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 @@ def validate_each(record, attribute, value)
|
||||
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 HelperMethods
|
||||
# * <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.
|
||||
#
|
||||
|
@ -331,6 +331,19 @@ def test_validates_length_of_with_block
|
||||
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)
|
||||
|
||||
|
@ -37,4 +37,8 @@ def my_validation_with_arg(attr)
|
||||
errors.add attr, "is missing" unless send(attr)
|
||||
end
|
||||
|
||||
def my_word_tokenizer(str)
|
||||
str.scan(/\w+/)
|
||||
end
|
||||
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user