1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Merge pull request #30674 from prognostikos/allow_procs_for_length_validator

Allow passing a Proc or Symbol as an argument to length validator values
This commit is contained in:
Rafael França 2017-10-26 11:27:21 -04:00 committed by GitHub
commit 12de5e202d
3 changed files with 43 additions and 2 deletions

View file

@ -1,3 +1,7 @@
* Allow passing a Proc or Symbol to length validator options.
*Matt Rohrer*
* Add method `#merge!` for `ActiveModel::Errors`.
*Jahfer Husain*

View file

@ -31,8 +31,8 @@ module ActiveModel
keys.each do |key|
value = options[key]
unless (value.is_a?(Integer) && value >= 0) || value == Float::INFINITY
raise ArgumentError, ":#{key} must be a nonnegative Integer or Infinity"
unless (value.is_a?(Integer) && value >= 0) || value == Float::INFINITY || value.is_a?(Symbol) || value.is_a?(Proc)
raise ArgumentError, ":#{key} must be a nonnegative Integer, Infinity, Symbol, or Proc"
end
end
end
@ -45,6 +45,12 @@ module ActiveModel
next unless check_value = options[key]
if !value.nil? || skip_nil_check?(key)
case check_value
when Proc
check_value = check_value.call(record)
when Symbol
check_value = record.send(check_value)
end
next if value_length.send(validity_check, check_value)
end

View file

@ -410,4 +410,35 @@ class LengthValidationTest < ActiveModel::TestCase
assert Topic.new("title" => "david").valid?
assert Topic.new("title" => "david2").invalid?
end
def test_validates_length_of_using_proc_as_maximum
Topic.validates_length_of :title, maximum: ->(model) { 5 }
t = Topic.new("title" => "valid", "content" => "whatever")
assert t.valid?
t.title = "notvalid"
assert t.invalid?
assert t.errors[:title].any?
assert_equal ["is too long (maximum is 5 characters)"], t.errors[:title]
t.title = ""
assert t.valid?
end
def test_validates_length_of_using_proc_as_maximum_with_model_method
Topic.send(:define_method, :max_title_length, lambda { 5 })
Topic.validates_length_of :title, maximum: Proc.new(&:max_title_length)
t = Topic.new("title" => "valid", "content" => "whatever")
assert t.valid?
t.title = "notvalid"
assert t.invalid?
assert t.errors[:title].any?
assert_equal ["is too long (maximum is 5 characters)"], t.errors[:title]
t.title = ""
assert t.valid?
end
end