lib/activefacts/api/instance.rb in activefacts-api-0.9.7 vs lib/activefacts/api/instance.rb in activefacts-api-0.9.8
- old
+ new
@@ -2,12 +2,10 @@
# ActiveFacts Runtime API
# Instance (mixin module for instances of a ObjectType - a class with ObjectType mixed in)
#
# Copyright (c) 2009 Clifford Heath. Read the LICENSE file.
#
-# Instance methods are extended into all instances, whether of value or entity types.
-#
module ActiveFacts
module API
# Every Instance of a ObjectType (A Value type or an Entity type) includes the methods of this module:
module Instance
# What constellation does this Instance belong to (if any):
@@ -34,10 +32,11 @@
# If this instance's role is updated to the new value, does that cause a collision?
# We need to check each superclass that has a different identification pattern
def check_identification_change_legality(role, value)
return unless @constellation && role.is_identifying
+ return if @constellation.send(:instance_variable_get, :@suspend_duplicate_key_check)
klasses = [self.class] + self.class.supertypes_transitive
last_identity = nil
last_irns = nil
counterpart_class = role.counterpart ? role.counterpart.object_type : value.class
@@ -81,28 +80,39 @@
@constellation.deindex_instance(self) if @constellation
# Now, for all roles (from this class and all supertypes), assign nil to all functional roles
# The counterpart roles get cleared automatically.
klasses = [self.class]+self.class.supertypes_transitive
+
+ irvks = {} # identifying_role_values by class
klasses.each do |klass|
+ if !irvks[klass] and klass.roles.detect{|_, role| role.counterpart and !role.counterpart.unique and send(role.getter) }
+ # We will need the identifying_role_values for this role's object_type
+ irvks[klass] = identifying_role_values(klass)
+ end
+ end
+
+ klasses.each do |klass|
klass.roles.each do |role_name, role|
next if role.unary?
counterpart = role.counterpart
# Objects being created do not have to have non-identifying mandatory roles,
# so we allow retracting to the same state.
if role.unique
i = send(role.getter)
next unless i
if counterpart.is_identifying && counterpart.mandatory
+ # We play a mandatory identifying role in i; so retract that (it'll clear our instance variable)
i.retract
else
if (counterpart.unique)
# REVISIT: This will incorrectly fail to propagate a key change for a non-mandatory role
i.send(counterpart.setter, nil, false)
else
- i.send(role.counterpart.getter).update(self, nil)
+ rv = i.send(role.counterpart.getter)
+ rv.delete_instance(self, irvks[role.object_type])
end
end
instance_variable_set(role.variable, nil)
else
# puts "Not removing role #{role_name} from counterpart RoleValues #{counterpart.name}"
@@ -123,13 +133,9 @@
end
module ClassMethods #:nodoc:
include ObjectType
# Add Instance class methods here
- end
-
- def self.included other #:nodoc:
- other.send :extend, ClassMethods
end
end
end
end