diff --git a/lib/couchrest/mixins/properties.rb b/lib/couchrest/mixins/properties.rb index a426670..aac1b66 100644 --- a/lib/couchrest/mixins/properties.rb +++ b/lib/couchrest/mixins/properties.rb @@ -35,7 +35,6 @@ module CouchRest def cast_keys return unless self.class.properties - # TODO move the argument checking to the cast method for early crashes self.class.properties.each do |property| next unless property.casted key = self.has_key?(property.name) ? property.name : property.name.to_sym @@ -44,17 +43,19 @@ module CouchRest klass = ::CouchRest.constantize(target[0]) self[property.name] = self[key].collect do |value| - obj = ( (property.init_method == 'send') && klass == Time) ? Time.parse(value) : klass.send(property.init_method, value) + # Auto parse Time objects + obj = ( (property.init_method == 'new') && klass == Time) ? Time.parse(value) : klass.send(property.init_method, value) obj.casted_by = self if obj.respond_to?(:casted_by) obj end else - # Let people use :send as a Time parse arg - self[property.name] = if ((property.init_method != 'send') && target == 'Time') - Time.parse(self[property.init_method]) + # Auto parse Time objects + self[property.name] = if ((property.init_method == 'new') && target == 'Time') + self[key].is_a?(String) ? Time.parse(self[key].dup) : self[key] else + # Let people use :send as a Time parse arg klass = ::CouchRest.constantize(target) - klass.send(property.init_method, self[property.name]) + klass.send(property.init_method, self[key]) end self[key].casted_by = self if self[key].respond_to?(:casted_by) end @@ -73,7 +74,7 @@ module CouchRest # make sure to use a mutex. def define_property(name, options={}) # check if this property is going to casted - options[:casted] = true if options[:cast_as] + options[:casted] = options[:cast_as] ? options[:cast_as] : false property = CouchRest::Property.new(name, (options.delete(:cast_as) || options.delete(:type)), options) create_property_getter(property) create_property_setter(property) unless property.read_only == true diff --git a/lib/couchrest/more/extended_document.rb b/lib/couchrest/more/extended_document.rb index e846340..d800ad2 100644 --- a/lib/couchrest/more/extended_document.rb +++ b/lib/couchrest/more/extended_document.rb @@ -38,8 +38,8 @@ module CouchRest # decent time format by default. See Time#to_json def self.timestamps! class_eval <<-EOS, __FILE__, __LINE__ - property(:updated_at, :read_only => true) - property(:created_at, :read_only => true) + property(:updated_at, :read_only => true, :cast_as => 'Time') + property(:created_at, :read_only => true, :cast_as => 'Time') save_callback :before do |object| object['updated_at'] = Time.now diff --git a/lib/couchrest/more/property.rb b/lib/couchrest/more/property.rb index 06628de..3bb4e3b 100644 --- a/lib/couchrest/more/property.rb +++ b/lib/couchrest/more/property.rb @@ -21,7 +21,7 @@ module CouchRest @alias = options.delete(:alias) if options[:alias] @default = options.delete(:default) if options[:default] @casted = options[:casted] ? true : false - @init_method = options[:send] ? options.delete[:send] : 'new' + @init_method = options[:send] ? options.delete(:send) : 'new' @options = options end diff --git a/spec/couchrest/core/model_spec.rb b/spec/couchrest/core/model_spec.rb index fdad16a..610a862 100644 --- a/spec/couchrest/core/model_spec.rb +++ b/spec/couchrest/core/model_spec.rb @@ -852,4 +852,5 @@ describe CouchRest::Model do @obj.attachment_url(@attachment_name).should == "#{Basic.database}/#{@obj.id}/#{@attachment_name}" end end + end \ No newline at end of file diff --git a/spec/couchrest/more/extended_doc_spec.rb b/spec/couchrest/more/extended_doc_spec.rb index 7096293..c1c10ef 100644 --- a/spec/couchrest/more/extended_doc_spec.rb +++ b/spec/couchrest/more/extended_doc_spec.rb @@ -3,15 +3,18 @@ require File.dirname(__FILE__) + '/../../spec_helper' class WithDefaultValues < CouchRest::ExtendedDocument use_database TEST_SERVER.default_database property :preset, :default => {:right => 10, :top_align => false} - property :set_by_proc, :default => Proc.new{Time.now}, :type => 'Time' + property :set_by_proc, :default => Proc.new{Time.now}, :cast_as => 'Time' + property :name + timestamps! end describe "ExtendedDocument" do + before(:each) do + @obj = WithDefaultValues.new + end + describe "with default" do - before(:each) do - @obj = WithDefaultValues.new - end it "should have the default value set at initalization" do @obj.preset.should == {:right => 10, :top_align => false} @@ -24,4 +27,36 @@ describe "ExtendedDocument" do end end + describe "timestamping" do + + it "should define the updated_at and created_at getters and set the values" do + @obj.save + obj = WithDefaultValues.get(@obj.id) + obj.created_at.should be_an_instance_of(Time) + obj.updated_at.should be_an_instance_of(Time) + obj.created_at.to_s.should == @obj.updated_at.to_s + end + + end + + describe "saving and retrieving" do + + it "should work fine" do + @obj.name = "should be easily saved and retrieved" + @obj.save + saved_obj = WithDefaultValues.get(@obj.id) + saved_obj.should_not be_nil + end + + it "should parse the Time attributes automatically" do + @obj.name = "should parse the Time attributes automatically" + @obj.set_by_proc.should be_an_instance_of(Time) + @obj.save + @obj.set_by_proc.should be_an_instance_of(Time) + saved_obj = WithDefaultValues.get(@obj.id) + saved_obj.set_by_proc.should be_an_instance_of(Time) + end + + end + end \ No newline at end of file