lib/activefacts/api/instance.rb in activefacts-api-0.9.5 vs lib/activefacts/api/instance.rb in activefacts-api-0.9.6

- old
+ new

@@ -32,23 +32,24 @@ super || self.class.supertypes_transitive.include?(klass) end # 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_value_change_legality(role, value) + def check_identification_change_legality(role, value) return unless @constellation && role.is_identifying klasses = [self.class] + self.class.supertypes_transitive last_identity = nil last_irns = nil + counterpart_class = role.counterpart ? role.counterpart.object_type : value.class duplicate = klasses.detect do |klass| next false unless klass.identifying_roles.include?(role) irns = klass.identifying_role_names if last_irns != irns last_identity = identifying_role_values(klass) role_position = irns.index(role.name) - last_identity[role_position] = value.identifying_role_values + last_identity[role_position] = value.identifying_role_values(counterpart_class) end @constellation.instances[klass][last_identity] end raise DuplicateIdentifyingValueException.new(self.class, role.name, value) if duplicate @@ -88,26 +89,35 @@ 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 - i = send(role.name) and i.retract + i.retract else - send role.setter, nil + 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) + end end + instance_variable_set(role.variable, nil) else # puts "Not removing role #{role_name} from counterpart RoleValues #{counterpart.name}" # Duplicate the array using to_a, as the RoleValues here will be modified as we traverse it: counterpart_instances = send(role.name) counterpart_instances.to_a.each do |counterpart_instance| # These actions deconstruct the RoleValues as we go: if counterpart.is_identifying && counterpart.mandatory counterpart_instance.retract else - counterpart_instance.send(counterpart.setter, nil) + counterpart_instance.send(counterpart.setter, nil, false) end end + instance_variable_set(role.variable, nil) end end end end