casted_by is now set on assignment to a document.

This commit is contained in:
Peter Gumeson 2009-05-28 17:56:42 -07:00
parent 3e4c90f104
commit efeb654114
3 changed files with 95 additions and 1 deletions

View file

@ -44,13 +44,14 @@ module CouchRest
target = property.type
if target.is_a?(Array)
klass = ::CouchRest.constantize(target[0])
self[property.name] = self[key].collect do |value|
arr = self[key].collect do |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.document_saved = true if obj.respond_to?(:document_saved)
obj
end
self[property.name] = target[0] != 'String' ? CastedArray.new(arr) : arr
else
# Auto parse Time objects
self[property.name] = if ((property.init_method == 'new') && target == 'Time')
@ -63,6 +64,7 @@ module CouchRest
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
self[property.name].casted_by = self if self[property.name].respond_to?(:casted_by)
end
end
@ -109,6 +111,14 @@ module CouchRest
meth = property.name
class_eval <<-EOS
def #{meth}=(value)
if #{property.casted} && value.is_a?(Array)
arr = CastedArray.new
arr.casted_by = self
value.each { |v| arr << v }
value = arr
elsif #{property.casted}
value.casted_by = self if value.respond_to?(:casted_by)
end
self['#{meth}'] = value
end
EOS

View file

@ -38,3 +38,22 @@ module CouchRest
end
end
class CastedArray < Array
attr_accessor :casted_by
def << obj
obj.casted_by = self.casted_by if obj.respond_to?(:casted_by)
super(obj)
end
def push(obj)
obj.casted_by = self.casted_by if obj.respond_to?(:casted_by)
super(obj)
end
def []= index, obj
obj.casted_by = self.casted_by if obj.respond_to?(:casted_by)
super(index, obj)
end
end

View file

@ -3,6 +3,7 @@ require File.join(FIXTURE_PATH, 'more', 'card')
require File.join(FIXTURE_PATH, 'more', 'invoice')
require File.join(FIXTURE_PATH, 'more', 'service')
require File.join(FIXTURE_PATH, 'more', 'event')
require File.join(FIXTURE_PATH, 'more', 'cat')
describe "ExtendedDocument properties" do
@ -131,6 +132,70 @@ describe "ExtendedDocument properties" do
@event['occurs_at'].should be_an_instance_of(Time)
end
end
end
end
describe "a newly created casted model" do
before(:each) do
reset_test_db!
@cat = Cat.new(:name => 'Toonces')
@squeaky_mouse = CatToy.new(:name => 'Squeaky')
end
describe "assigned assigned to a casted property" do
it "should have casted_by set to its parent" do
@squeaky_mouse.casted_by.should be_nil
@cat.favorite_toy = @squeaky_mouse
@squeaky_mouse.casted_by.should === @cat
end
end
describe "appended to a casted collection" do
it "should have casted_by set to its parent" do
@squeaky_mouse.casted_by.should be_nil
@cat.toys << @squeaky_mouse
@squeaky_mouse.casted_by.should === @cat
@cat.save
@cat.toys.first.casted_by.should === @cat
end
end
describe "list assigned to a casted collection" do
it "should have casted_by set on all elements" do
toy1 = CatToy.new(:name => 'Feather')
toy2 = CatToy.new(:name => 'Mouse')
@cat.toys = [toy1, toy2]
toy1.casted_by.should === @cat
toy2.casted_by.should === @cat
@cat.save
@cat = Cat.get(@cat.id)
@cat.toys[0].casted_by.should === @cat
@cat.toys[1].casted_by.should === @cat
end
end
end
describe "a casted model retrieved from the database" do
before(:each) do
reset_test_db!
@cat = Cat.new(:name => 'Stimpy')
@cat.favorite_toy = CatToy.new(:name => 'Stinky')
@cat.toys << CatToy.new(:name => 'Feather')
@cat.toys << CatToy.new(:name => 'Mouse')
@cat.save
@cat = Cat.get(@cat.id)
end
describe "as a casted property" do
it "should already be casted_by its parent" do
@cat.favorite_toy.casted_by.should === @cat
end
end
describe "from a casted collection" do
it "should already be casted_by its parent" do
@cat.toys[0].casted_by.should === @cat
@cat.toys[1].casted_by.should === @cat
end
end
end