From eed682e16f25783739c0bfa0e1afe12dd2373a15 Mon Sep 17 00:00:00 2001 From: Frederick Cheung Date: Fri, 18 Feb 2011 17:55:29 +0000 Subject: [PATCH] Change validates inclusion to use cover? for Ranges in ruby 1.9 --- .../lib/active_model/validations/inclusion.rb | 22 +++++++++++++++++-- .../cases/validations/inclusion_validation_test.rb | 10 +++++++++ 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/activemodel/lib/active_model/validations/inclusion.rb b/activemodel/lib/active_model/validations/inclusion.rb index 049b093..e5c2214 100644 --- a/activemodel/lib/active_model/validations/inclusion.rb +++ b/activemodel/lib/active_model/validations/inclusion.rb @@ -8,9 +8,25 @@ module ActiveModel ":in option of the configuration hash" unless options[:in].respond_to?(:include?) end - def validate_each(record, attribute, value) - unless options[:in].include?(value) - record.errors.add(attribute, :inclusion, options.except(:in).merge!(:value => value)) + #On ruby 1.9 Range#include? checks all possible values in the Range for equality, so is much slower for large ranges + #A cover? method is added that uses the previous logic of comparing a value with the range endpoints + if (1..2).respond_to?(:cover?) + def validate_each(record, attribute, value) + included = if options[:in].is_a?(Range) + options[:in].cover?(value) + else + options[:in].include?(value) + end + + unless included + record.errors.add(attribute, :inclusion, options.except(:in).merge!(:value => value)) + end + end + else + def validate_each(record, attribute, value) + unless options[:in].include?(value) + record.errors.add(attribute, :inclusion, options.except(:in).merge!(:value => value)) + end end end end diff --git a/activemodel/test/cases/validations/inclusion_validation_test.rb b/activemodel/test/cases/validations/inclusion_validation_test.rb index 0716b4f..dfa3f38 100644 --- a/activemodel/test/cases/validations/inclusion_validation_test.rb +++ b/activemodel/test/cases/validations/inclusion_validation_test.rb @@ -9,6 +9,16 @@ class InclusionValidationTest < ActiveModel::TestCase def teardown Topic.reset_callbacks(:validate) end + + def test_validates_inclusion_of_range + Topic.validates_inclusion_of( :title, :in => 'aaa'..'bbb') + assert Topic.new("title" => "bbc", "content" => "abc").invalid? + assert Topic.new("title" => "aa", "content" => "abc").invalid? + assert Topic.new("title" => "aaa", "content" => "abc").valid? + assert Topic.new("title" => "abc", "content" => "abc").valid? + assert Topic.new("title" => "bbb", "content" => "abc").valid? + end + def test_validates_inclusion_of Topic.validates_inclusion_of( :title, :in => %w( a b c d e f g ) ) -- 1.7.3.3