From 23341f36984ae0110640bf691620c9202fc40e8a Mon Sep 17 00:00:00 2001 From: Peter Gumeson Date: Thu, 28 May 2009 16:09:53 -0700 Subject: [PATCH] Added new_model? and new_record? alias to casted model for rails compatibility. --- lib/couchrest/mixins/properties.rb | 2 ++ lib/couchrest/more/casted_model.rb | 8 +++++ lib/couchrest/more/extended_document.rb | 18 +++++++++++ spec/couchrest/more/casted_model_spec.rb | 41 ++++++++++++++++++++++++ 4 files changed, 69 insertions(+) diff --git a/lib/couchrest/mixins/properties.rb b/lib/couchrest/mixins/properties.rb index 19d33d1..676f045 100644 --- a/lib/couchrest/mixins/properties.rb +++ b/lib/couchrest/mixins/properties.rb @@ -48,6 +48,7 @@ module CouchRest # 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.document_saved = true if obj.respond_to?(:document_saved) obj end else @@ -60,6 +61,7 @@ module CouchRest klass.send(property.init_method, self[key].dup) end self[property.name].casted_by = self if self[property.name].respond_to?(:casted_by) + self[property.name].document_saved = true if self[property.name].respond_to?(:document_saved) end end end diff --git a/lib/couchrest/more/casted_model.rb b/lib/couchrest/more/casted_model.rb index 03f441f..bed9c7b 100644 --- a/lib/couchrest/more/casted_model.rb +++ b/lib/couchrest/more/casted_model.rb @@ -6,6 +6,7 @@ module CouchRest def self.included(base) base.send(:include, CouchRest::Mixins::Properties) base.send(:attr_accessor, :casted_by) + base.send(:attr_accessor, :document_saved) end def initialize(keys={}) @@ -26,6 +27,13 @@ module CouchRest super(key.to_s) end + # True if the casted model has already + # been saved in the containing document + def new_model? + !@document_saved + end + alias :new_record? :new_model? + # Sets the attributes from a hash def update_attributes_without_saving(hash) hash.each do |k, v| diff --git a/lib/couchrest/more/extended_document.rb b/lib/couchrest/more/extended_document.rb index 4d08db5..dfe4f0d 100644 --- a/lib/couchrest/more/extended_document.rb +++ b/lib/couchrest/more/extended_document.rb @@ -201,6 +201,7 @@ module CouchRest raise ArgumentError, "a document requires a database to be saved to (The document or the #{self.class} default database were not set)" unless database set_unique_id if new_document? && self.respond_to?(:set_unique_id) result = database.save_doc(self, bulk) + mark_as_saved if result["ok"] == true result["ok"] == true end @@ -226,5 +227,22 @@ module CouchRest end end + protected + + # Set document_saved flag on all casted models to true + def mark_as_saved + self.each do |key, prop| + if prop.is_a?(Array) + prop.each do |item| + if item.respond_to?(:document_saved) + item.send(:document_saved=, true) + end + end + elsif prop.respond_to?(:document_saved) + prop.send(:document_saved=, true) + end + end + end + end end diff --git a/spec/couchrest/more/casted_model_spec.rb b/spec/couchrest/more/casted_model_spec.rb index 43524a8..b493656 100644 --- a/spec/couchrest/more/casted_model_spec.rb +++ b/spec/couchrest/more/casted_model_spec.rb @@ -258,4 +258,45 @@ describe CouchRest::CastedModel do end end end + + describe "calling new_model? on a casted model" do + before :each do + reset_test_db! + @cat = Cat.new(:name => 'Sockington') + @cat.favorite_toy = CatToy.new(:name => 'Catnip Ball') + @cat.toys << CatToy.new(:name => 'Fuzzy Stick') + end + + it "should be true on new" do + CatToy.new.new_model?.should be_true + CatToy.new.new_record?.should be_true + end + + it "should be true after assignment" do + @cat.favorite_toy.new_model?.should be_true + @cat.toys.first.new_model?.should be_true + end + + it "should not be true after create or save" do + @cat.create + @cat.save + @cat.favorite_toy.new_model?.should be_false + @cat.toys.first.new_model?.should be_false + end + + it "should not be true after get from the database" do + @cat.save + @cat = Cat.get(@cat.id) + @cat.favorite_toy.new_model?.should be_false + @cat.toys.first.new_model?.should be_false + end + + it "should still be true after a failed create or save" do + @cat.name = nil + @cat.create.should be_false + @cat.save.should be_false + @cat.favorite_toy.new_model?.should be_true + @cat.toys.first.new_model?.should be_true + end + end end