From cdc4f20f309d87a4f78954c6ef5e2df537748942 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Fri, 11 Mar 2011 10:54:59 +0800 Subject: [PATCH] Make numeric fields work with validates_numericality_of using symbols and procs --- lib/simple_form/inputs/numeric_input.rb | 12 ++++++++-- test/inputs_test.rb | 32 +++++++++++++++++++++++++ test/support/models.rb | 20 +++++++++++++++- test/test_helper.rb | 1 + 4 files changed, 62 insertions(+), 3 deletions(-) diff --git a/lib/simple_form/inputs/numeric_input.rb b/lib/simple_form/inputs/numeric_input.rb index e69ca86e..ff674f7c 100644 --- a/lib/simple_form/inputs/numeric_input.rb +++ b/lib/simple_form/inputs/numeric_input.rb @@ -35,7 +35,7 @@ module SimpleForm def minimum_value(validator_options) if integer? && validator_options.key?(:greater_than) - validator_options[:greater_than] + 1 + sanitize_validator_option(validator_options[:greater_than]) + 1 else validator_options[:greater_than_or_equal_to] end @@ -43,7 +43,7 @@ module SimpleForm def maximum_value(validator_options) if integer? && validator_options.key?(:less_than) - validator_options[:less_than] - 1 + sanitize_validator_option(validator_options[:less_than]) - 1 else validator_options[:less_than_or_equal_to] end @@ -52,6 +52,14 @@ module SimpleForm def find_numericality_validator attribute_validators.find { |v| ActiveModel::Validations::NumericalityValidator === v } end + + private + + def sanitize_validator_option(option) + return option if option.is_a?(Numeric) + return object.send(option) if option.is_a?(Symbol) + return option.call(object) if option.respond_to?(:call) + end end end end diff --git a/test/inputs_test.rb b/test/inputs_test.rb index baa4c6a7..9af278e1 100644 --- a/test/inputs_test.rb +++ b/test/inputs_test.rb @@ -204,6 +204,22 @@ class InputTest < ActionView::TestCase assert_select 'input[min=18]' end + test 'input should infer min value from integer attributes with greater than validation using symbol' do + with_input_for @validating_user, :amount, :float + assert_no_select 'input[min]' + + with_input_for @validating_user, :amount, :integer + assert_select 'input[min=11]' + end + + test 'input should infer min value from integer attributes with greater than validation using proc' do + with_input_for @other_validating_user, :amount, :float + assert_no_select 'input[min]' + + with_input_for @other_validating_user, :amount, :integer + assert_select 'input[min=20]' + end + test 'input should infer max value from attributes with less than validation' do with_input_for @other_validating_user, :age, :float assert_no_select 'input[max]' @@ -212,6 +228,22 @@ class InputTest < ActionView::TestCase assert_select 'input[max=99]' end + test 'input should infer max value from attributes with less than validation using symbol' do + with_input_for @validating_user, :amount, :float + assert_no_select 'input[max]' + + with_input_for @validating_user, :amount, :integer + assert_select 'input[max=99]' + end + + test 'input should infer max value from attributes with less than validation using proc' do + with_input_for @other_validating_user, :amount, :float + assert_no_select 'input[max]' + + with_input_for @other_validating_user, :amount, :integer + assert_select 'input[max=118]' + end + test 'input should infer step value only from integer attribute' do with_input_for @validating_user, :age, :float assert_no_select 'input[step]' diff --git a/test/support/models.rb b/test/support/models.rb index 28084259..f7b950f6 100644 --- a/test/support/models.rb +++ b/test/support/models.rb @@ -40,7 +40,8 @@ class User attr_accessor :id, :name, :company, :company_id, :time_zone, :active, :description, :created_at, :updated_at, :credit_limit, :age, :password, :delivery_time, :born_at, :special_company_id, :country, :url, :tag_ids, - :avatar, :home_picture, :email, :status, :residence_country, :phone_number, :post_count, :lock_version + :avatar, :home_picture, :email, :status, :residence_country, :phone_number, :post_count, :lock_version, + :amount def initialize(options={}) options.each do |key, value| @@ -72,6 +73,7 @@ class User when :updated_at then :timestamp when :lock_version then :integer when :home_picture then :string + when :amount then :integer end Column.new(attribute, column_type, limit) end @@ -124,6 +126,18 @@ class ValidatingUser < User :greater_than_or_equal_to => 18, :less_than_or_equal_to => 99, :only_integer => true + validates_numericality_of :amount, + :greater_than => :min_amount, + :less_than => :max_amount, + :only_integer => true + + def min_amount + 10 + end + + def max_amount + 100 + end end class OtherValidatingUser < User @@ -132,4 +146,8 @@ class OtherValidatingUser < User :greater_than => 17, :less_than => 100, :only_integer => true + validates_numericality_of :amount, + :greater_than => Proc.new { |user| user.age }, + :less_than => Proc.new { |user| user.age + 100}, + :only_integer => true end diff --git a/test/test_helper.rb b/test/test_helper.rb index 2d84feea..e1b7f7e2 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -58,6 +58,7 @@ class ActionView::TestCase :description => 'Hello!', :created_at => Time.now, :age => 19, + :amount => 15, :company => 1 }.merge(options))