Fixing dirty tracking on collection_of association type
This commit is contained in:
parent
fba1e53e20
commit
938bf2cf2c
|
@ -9,6 +9,7 @@
|
||||||
* Initialization blocks when creating new models (Peter Williams)
|
* Initialization blocks when creating new models (Peter Williams)
|
||||||
* Removed railties dependency (DAddYE)
|
* Removed railties dependency (DAddYE)
|
||||||
* DesignDoc cache refreshed if a database is deleted.
|
* DesignDoc cache refreshed if a database is deleted.
|
||||||
|
* Fixing dirty tracking on collection_of association.
|
||||||
|
|
||||||
|
|
||||||
## 1.1.0.beta5 - 2011-04-30
|
## 1.1.0.beta5 - 2011-04-30
|
||||||
|
|
|
@ -153,7 +153,7 @@ module CouchRest
|
||||||
def #{attrib}(reload = false)
|
def #{attrib}(reload = false)
|
||||||
return @#{attrib} unless @#{attrib}.nil? or reload
|
return @#{attrib} unless @#{attrib}.nil? or reload
|
||||||
ary = self.#{options[:foreign_key]}.collect{|i| #{options[:proxy]}.get(i)}
|
ary = self.#{options[:foreign_key]}.collect{|i| #{options[:proxy]}.get(i)}
|
||||||
@#{attrib} = ::CouchRest::CollectionOfProxy.new(ary, self, '#{options[:foreign_key]}')
|
@#{attrib} = ::CouchRest::Model::CollectionOfProxy.new(ary, find_property('#{options[:foreign_key]}'), self)
|
||||||
end
|
end
|
||||||
EOS
|
EOS
|
||||||
end
|
end
|
||||||
|
@ -161,7 +161,7 @@ module CouchRest
|
||||||
def create_collection_of_setter(attrib, options)
|
def create_collection_of_setter(attrib, options)
|
||||||
class_eval <<-EOS, __FILE__, __LINE__ + 1
|
class_eval <<-EOS, __FILE__, __LINE__ + 1
|
||||||
def #{attrib}=(value)
|
def #{attrib}=(value)
|
||||||
@#{attrib} = ::CouchRest::CollectionOfProxy.new(value, self, '#{options[:foreign_key]}')
|
@#{attrib} = ::CouchRest::Model::CollectionOfProxy.new(value, find_property('#{options[:foreign_key]}'), self)
|
||||||
end
|
end
|
||||||
EOS
|
EOS
|
||||||
end
|
end
|
||||||
|
@ -169,67 +169,63 @@ module CouchRest
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
# Special proxy for a collection of items so that adding and removing
|
# Special proxy for a collection of items so that adding and removing
|
||||||
# to the list automatically updates the associated property.
|
# to the list automatically updates the associated property.
|
||||||
class CollectionOfProxy < Array
|
class CollectionOfProxy < CastedArray
|
||||||
attr_accessor :property
|
|
||||||
attr_accessor :casted_by
|
|
||||||
|
|
||||||
def initialize(array, casted_by, property)
|
def initialize(array, property, parent)
|
||||||
self.property = property
|
(array ||= []).compact!
|
||||||
self.casted_by = casted_by
|
super(array, property, parent)
|
||||||
(array ||= []).compact!
|
casted_by[casted_by_property.to_s] = [] # replace the original array!
|
||||||
casted_by[property.to_s] = [] # replace the original array!
|
array.compact.each do |obj|
|
||||||
array.compact.each do |obj|
|
check_obj(obj)
|
||||||
check_obj(obj)
|
casted_by[casted_by_property.to_s] << obj.id
|
||||||
casted_by[property.to_s] << obj.id
|
end
|
||||||
end
|
end
|
||||||
super(array)
|
|
||||||
end
|
|
||||||
|
|
||||||
def << obj
|
def << obj
|
||||||
check_obj(obj)
|
check_obj(obj)
|
||||||
casted_by[property.to_s] << obj.id
|
casted_by[casted_by_property.to_s] << obj.id
|
||||||
super(obj)
|
super(obj)
|
||||||
end
|
end
|
||||||
|
|
||||||
def push(obj)
|
def push(obj)
|
||||||
check_obj(obj)
|
check_obj(obj)
|
||||||
casted_by[property.to_s].push obj.id
|
casted_by[casted_by_property.to_s].push obj.id
|
||||||
super(obj)
|
super(obj)
|
||||||
end
|
end
|
||||||
|
|
||||||
def unshift(obj)
|
def unshift(obj)
|
||||||
check_obj(obj)
|
check_obj(obj)
|
||||||
casted_by[property.to_s].unshift obj.id
|
casted_by[casted_by_property.to_s].unshift obj.id
|
||||||
super(obj)
|
super(obj)
|
||||||
end
|
end
|
||||||
|
|
||||||
def []= index, obj
|
def []= index, obj
|
||||||
check_obj(obj)
|
check_obj(obj)
|
||||||
casted_by[property.to_s][index] = obj.id
|
casted_by[casted_by_property.to_s][index] = obj.id
|
||||||
super(index, obj)
|
super(index, obj)
|
||||||
end
|
end
|
||||||
|
|
||||||
def pop
|
def pop
|
||||||
casted_by[property.to_s].pop
|
casted_by[casted_by_property.to_s].pop
|
||||||
super
|
super
|
||||||
end
|
end
|
||||||
|
|
||||||
def shift
|
def shift
|
||||||
casted_by[property.to_s].shift
|
casted_by[casted_by_property.to_s].shift
|
||||||
super
|
super
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
|
def check_obj(obj)
|
||||||
|
raise "Object cannot be added to #{casted_by.class.to_s}##{casted_by_property.to_s} collection unless saved" if obj.new?
|
||||||
|
end
|
||||||
|
|
||||||
def check_obj(obj)
|
|
||||||
raise "Object cannot be added to #{casted_by.class.to_s}##{property.to_s} collection unless saved" if obj.new?
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -101,7 +101,7 @@ describe "Assocations" do
|
||||||
it "should create an associated property and collection proxy" do
|
it "should create an associated property and collection proxy" do
|
||||||
@invoice.respond_to?('entry_ids').should be_true
|
@invoice.respond_to?('entry_ids').should be_true
|
||||||
@invoice.respond_to?('entry_ids=').should be_true
|
@invoice.respond_to?('entry_ids=').should be_true
|
||||||
@invoice.entries.class.should eql(::CouchRest::CollectionOfProxy)
|
@invoice.entries.class.should eql(::CouchRest::Model::CollectionOfProxy)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should allow replacement of objects" do
|
it "should allow replacement of objects" do
|
||||||
|
@ -154,6 +154,33 @@ describe "Assocations" do
|
||||||
@invoice.entries.should be_empty
|
@invoice.entries.should be_empty
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Account for dirty tracking
|
||||||
|
describe "dirty tracking" do
|
||||||
|
it "should register changes on push" do
|
||||||
|
@invoice.changed?.should be_false
|
||||||
|
@invoice.entries << @entries[0]
|
||||||
|
@invoice.changed?.should be_true
|
||||||
|
end
|
||||||
|
it "should register changes on pop" do
|
||||||
|
@invoice.entries << @entries[0]
|
||||||
|
@invoice.save
|
||||||
|
@invoice.changed?.should be_false
|
||||||
|
@invoice.entries.pop
|
||||||
|
@invoice.changed?.should be_true
|
||||||
|
end
|
||||||
|
it "should register id changes on push" do
|
||||||
|
@invoice.entry_ids << @entries[0].id
|
||||||
|
@invoice.changed?.should be_true
|
||||||
|
end
|
||||||
|
it "should register id changes on pop" do
|
||||||
|
@invoice.entry_ids << @entries[0].id
|
||||||
|
@invoice.save
|
||||||
|
@invoice.changed?.should be_false
|
||||||
|
@invoice.entry_ids.pop
|
||||||
|
@invoice.changed?.should be_true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "proxy" do
|
describe "proxy" do
|
||||||
|
|
||||||
it "should ensure new entries to proxy are matched" do
|
it "should ensure new entries to proxy are matched" do
|
||||||
|
|
Loading…
Reference in a new issue