diff --git a/lib/validates_timeliness.rb b/lib/validates_timeliness.rb index 88eab8d..4a09111 100644 --- a/lib/validates_timeliness.rb +++ b/lib/validates_timeliness.rb @@ -8,9 +8,9 @@ require 'validates_timeliness/active_record/multiparameter_attributes' require 'validates_timeliness/action_view/instance_tag' module ValidatesTimeliness - + mattr_accessor :default_timezone - self.default_timezone = :utc + self.default_timezone = :utc mattr_accessor :use_time_zones self.use_time_zones = false @@ -25,18 +25,18 @@ module ValidatesTimeliness end def load_error_messages + defaults = YAML::load(IO.read(LOCALE_PATH))['en'] + ValidatesTimeliness::Validator.error_value_formats = defaults['validates_timeliness']['error_value_formats'].symbolize_keys + if defined?(I18n) I18n.load_path.unshift(LOCALE_PATH) I18n.reload! else - defaults = YAML::load(IO.read(LOCALE_PATH))['en'] errors = defaults['activerecord']['errors']['messages'].inject({}) {|h,(k,v)| h[k.to_sym] = v.gsub(/\{\{\w*\}\}/, '%s');h } ::ActiveRecord::Errors.default_error_messages.update(errors) - - ValidatesTimeliness::Validator.error_value_formats = defaults['validates_timeliness']['error_value_formats'].symbolize_keys end end - + def setup_for_rails self.default_timezone = ::ActiveRecord::Base.default_timezone self.use_time_zones = ::ActiveRecord::Base.time_zone_aware_attributes rescue false diff --git a/lib/validates_timeliness/validator.rb b/lib/validates_timeliness/validator.rb index 0928c3c..9d007ad 100644 --- a/lib/validates_timeliness/validator.rb +++ b/lib/validates_timeliness/validator.rb @@ -1,16 +1,17 @@ module ValidatesTimeliness class Validator + cattr_accessor :error_value_formats cattr_accessor :ignore_restriction_errors self.ignore_restriction_errors = false RESTRICTION_METHODS = { :equal_to => :==, - :before => :<, - :after => :>, + :before => :<, + :after => :>, :on_or_before => :<=, :on_or_after => :>=, - :between => lambda {|v, r| (r.first..r.last).include?(v) } + :between => lambda {|v, r| (r.first..r.last).include?(v) } } VALID_OPTIONS = [ @@ -27,7 +28,7 @@ module ValidatesTimeliness @type = @configuration.delete(:type) validate_options(@configuration) end - + def call(record, attr_name, value) raw_value = raw_value(record, attr_name) || value @@ -52,7 +53,7 @@ module ValidatesTimeliness def raw_value(record, attr_name) record.send("#{attr_name}_before_type_cast") rescue nil end - + def validate_restrictions(record, attr_name, value) if configuration[:with_time] || configuration[:with_date] value = combine_date_and_time(value, record) @@ -81,7 +82,7 @@ module ValidatesTimeliness end def interpolation_values(option, restriction) - format = self.class.error_value_formats[type] + format = self.class.error_value_format_for(type) restriction = [restriction] unless restriction.is_a?(Array) if defined?(I18n) @@ -105,7 +106,7 @@ module ValidatesTimeliness comparator.call(value, restriction) end end - + def add_error(record, attr_name, message, interpolate=nil) if defined?(I18n) custom = custom_error_messages[message] @@ -119,7 +120,7 @@ module ValidatesTimeliness def custom_error_messages @custom_error_messages ||= configuration.inject({}) {|msgs, (k, v)| - if md = /(.*)_message$/.match(k.to_s) + if md = /(.*)_message$/.match(k.to_s) msgs[md[1].to_sym] = v end msgs @@ -147,7 +148,7 @@ module ValidatesTimeliness end def implied_type - @implied_type ||= configuration[:with_date] || configuration[:with_time] ? :datetime : type + @implied_type ||= configuration[:with_date] || configuration[:with_time] ? :datetime : type end # class methods @@ -161,18 +162,14 @@ module ValidatesTimeliness end end - def error_value_formats + def error_value_format_for(type) if defined?(I18n) - I18n.t('validates_timeliness.error_value_formats') + I18n.t(type, :default => error_value_formats[type], :scope => 'validates_timeliness.error_value_formats') else - @@error_value_formats + error_value_formats[type] end end - def error_value_formats=(formats) - @@error_value_formats = formats - end - def evaluate_option_value(value, type, record) case value when Time, Date diff --git a/spec/validator_spec.rb b/spec/validator_spec.rb index 92297da..e5518dc 100644 --- a/spec/validator_spec.rb +++ b/spec/validator_spec.rb @@ -305,7 +305,7 @@ describe ValidatesTimeliness::Validator do validate_with(:birth_date, 1.day.from_now.to_date) should_have_no_error(:birth_date, :between) end - + it "should allow a range for between restriction" do configure_validator(:type => :date, :between => (1.day.ago.to_date)..(1.day.from_now.to_date)) validate_with(:birth_date, 1.day.from_now.to_date) @@ -566,6 +566,24 @@ describe ValidatesTimeliness::Validator do validate_with(:birth_time, '11:59') person.errors.on(:birth_time).should match(/after \d{2}:\d{2}:\d{2}\Z/) end + + if defined?(I18n) + + describe "I18n" do + it "should use global default if locale format missing" do + I18n.backend.store_translations 'zz', :activerecord => {:errors => {:messages => { :after => 'after {{restriction}}' }}} + I18n.locale = :zz + configure_validator(:type => :datetime, :after => 1.day.from_now) + validate_with(:birth_date_and_time, Time.now) + person.errors.on(:birth_date_and_time).should match(/after \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\Z/) + end + + after do + I18n.locale = :en + end + end + + end end describe "custom formats" do @@ -644,7 +662,7 @@ describe ValidatesTimeliness::Validator do def error_messages return @error_messages if defined?(@error_messages) - messages = validator.send(:error_messages) + messages = defined?(I18n) ? I18n.t('activerecord.errors.messages') : validator.send(:error_messages) @error_messages = messages.inject({}) {|h, (k, v)| h[k] = v.sub(/ (\%s|\{\{\w*\}\}).*/, ''); h } end end