diff --git a/lib/validates_timeliness.rb b/lib/validates_timeliness.rb index 992da07..787aea3 100644 --- a/lib/validates_timeliness.rb +++ b/lib/validates_timeliness.rb @@ -29,13 +29,17 @@ module ValidatesTimeliness # Setup method for plugin configuration def self.setup yield self - extend_classes.each {|klass| klass.send(:include, ValidatesTimeliness::HelperMethods) } + extend_classes.each {|klass| + klass.send(:include, ValidatesTimeliness::HelperMethods) + klass.send(:include, ValidatesTimeliness::AttributeMethods) + } end end require 'validates_timeliness/conversion' require 'validates_timeliness/validator' require 'validates_timeliness/helper_methods' +require 'validates_timeliness/attribute_methods' require 'validates_timeliness/extensions' require 'validates_timeliness/version' diff --git a/lib/validates_timeliness/attribute_methods.rb b/lib/validates_timeliness/attribute_methods.rb new file mode 100644 index 0000000..fe9f0de --- /dev/null +++ b/lib/validates_timeliness/attribute_methods.rb @@ -0,0 +1,43 @@ +module ValidatesTimeliness + module AttributeMethods + extend ActiveSupport::Concern + + included do + attribute_method_suffix "_before_type_cast" + end + + module ClassMethods + + protected + + def define_method_attribute=(attr_name) + if timeliness_validated_attributes.include?(attr_name) + method_body, line = <<-EOV, __LINE__ + 1 + def #{attr_name}=(value) + @attributes_cache ||= {} + @attributes_cache["_#{attr_name}_before_type_cast"] = value + super + end + EOV + class_eval(method_body, __FILE__, line) + else + super + end + end + + def define_method_attribute_before_type_cast(attr_name) + if timeliness_validated_attributes.include?(attr_name) + method_body, line = <<-EOV, __LINE__ + 1 + def #{attr_name}_before_type_cast + @attributes_cache && @attributes_cache["_#{attr_name}_before_type_cast"] + end + EOV + class_eval(method_body, __FILE__, line) + else + super rescue(NoMethodError) + end + end + + end + end +end diff --git a/lib/validates_timeliness/helper_methods.rb b/lib/validates_timeliness/helper_methods.rb index c208300..bf3af71 100644 --- a/lib/validates_timeliness/helper_methods.rb +++ b/lib/validates_timeliness/helper_methods.rb @@ -20,5 +20,15 @@ module ValidatesTimeliness validates_with Validator, _merge_attributes(attr_names).merge(:type => :datetime) end end + + module ClassMethods + def timeliness_validated_attributes + @timeliness_validated_attributes ||= begin + _validators.map do |attr_name, validators| + attr_name.to_s if validators.any? {|v| v.is_a?(ValidatesTimeliness::Validator) } + end.compact + end + end + end end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 0ed8020..14c5eb7 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -25,12 +25,15 @@ LOCALE_PATH = File.expand_path(File.dirname(__FILE__) + '/../lib/validates_timel I18n.load_path.unshift(LOCALE_PATH) class Person + include ActiveModel::AttributeMethods include ActiveModel::Validations extend ActiveModel::Translation attr_accessor :birth_date, :birth_time, :birth_datetime + attr_accessor :attributes def initialize(attributes = {}) + @attributes = {} attributes.each do |key, value| send "#{key}=", value end diff --git a/spec/validates_timeliness/attribute_methods_spec.rb b/spec/validates_timeliness/attribute_methods_spec.rb new file mode 100644 index 0000000..d2db27e --- /dev/null +++ b/spec/validates_timeliness/attribute_methods_spec.rb @@ -0,0 +1,22 @@ +require 'spec_helper' + +describe ValidatesTimeliness::AttributeMethods do + before do + Employee.validates_datetime :birth_datetime + Employee.define_attribute_methods + end + + it 'should define attribute write method for validated attributes' do + Employee.instance_methods(false).should include("birth_datetime=") + end + + it 'should define attribute before_type_cast method for validated attributes' do + Employee.instance_methods(false).should include("birth_datetime_before_type_cast") + end + + it 'should store original raw value on attribute write' do + r = Employee.new + r.birth_datetime = '2010-01-01' + r.birth_datetime_before_type_cast.should == '2010-01-01' + end +end diff --git a/spec/validates_timeliness/helper_methods_spec.rb b/spec/validates_timeliness/helper_methods_spec.rb index bc480a4..87d1433 100644 --- a/spec/validates_timeliness/helper_methods_spec.rb +++ b/spec/validates_timeliness/helper_methods_spec.rb @@ -12,4 +12,11 @@ describe ValidatesTimeliness::HelperMethods do ActiveRecord::Base.instance_methods.should include('validates_time') ActiveRecord::Base.instance_methods.should include('validates_datetime') end + + describe ".timeliness_validated_attributes" do + it 'should return attributes validated with plugin validator' do + Person.validates_date :birth_date + Person.timeliness_validated_attributes.should == ["birth_date"] + end + end end