Module: ActiveFacts::API::Instance
Overview
Every Instance of a ObjectType (A Value type or an Entity type) includes the methods of this module:
Defined Under Namespace
Modules: ClassMethods
Instance Attribute Summary collapse
-
#constellation ⇒ Object
readonly
What constellation does this Instance belong to (if any):.
Instance Method Summary collapse
-
#check_identification_change_legality(role, value) ⇒ Object
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.
-
#initialize(args = []) ⇒ Object
:nodoc:.
- #instance_index ⇒ Object
- #is_a?(klass) ⇒ Boolean
-
#related_entities(indirectly = true, instances = []) ⇒ Object
List entities which have an identifying role played by this object.
-
#retract ⇒ Object
De-assign all functional roles and remove from constellation, if any.
Instance Attribute Details
#constellation ⇒ Object (readonly)
What constellation does this Instance belong to (if any):
12 13 14 |
# File 'lib/activefacts/api/instance.rb', line 12 def constellation @constellation end |
Instance Method Details
#check_identification_change_legality(role, value) ⇒ Object
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
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/activefacts/api/instance.rb', line 35 def check_identification_change_legality(role, value) return unless @constellation && role. 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 duplicate = klasses.detect do |klass| next false unless klass..include?(role) irns = klass. if last_irns != irns last_identity = (klass) role_position = irns.index(role.name) last_identity[role_position] = value.(counterpart_class) end @constellation.instances[klass][last_identity] end raise .new(self.class, role.name, value) if duplicate end |
#initialize(args = []) ⇒ Object
:nodoc:
14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# File 'lib/activefacts/api/instance.rb', line 14 def initialize(args = []) #:nodoc: unless (self.class.is_entity_type) begin super(*args) rescue TypeError => e if trace(:debug) p e; puts e.backtrace*"\n\t"; debugger; true end rescue ArgumentError => e e. << " constructing a #{self.class}" raise end end end |
#instance_index ⇒ Object
73 74 75 |
# File 'lib/activefacts/api/instance.rb', line 73 def instance_index @constellation.send(self.class.basename.to_sym) end |
#is_a?(klass) ⇒ Boolean
29 30 31 |
# File 'lib/activefacts/api/instance.rb', line 29 def is_a? klass super || self.class.supertypes_transitive.include?(klass) end |
#related_entities(indirectly = true, instances = []) ⇒ Object
List entities which have an identifying role played by this object.
58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/activefacts/api/instance.rb', line 58 def (indirectly = true, instances = []) # Check all roles of this instance self.class.all_role.each do |role_name, role| # If the counterpart role is not identifying for its object type, skip it next unless c = role.counterpart and c. identified_instances = Array(self.send(role.getter)) instances.concat(identified_instances) identified_instances.each do |instance| instance.(indirectly, instances) if indirectly end end instances end |
#retract ⇒ Object
De-assign all functional roles and remove from constellation, if any.
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/activefacts/api/instance.rb', line 78 def retract # Delete from the constellation first, while we remember our identifying role values @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 irvrvs = {} # identifying_role_values by RoleValues self.class.all_role_transitive.each do |_, role| next unless role.counterpart and role.unique and !role.counterpart.unique and counterpart = send(role.getter) role_values = counterpart.send(role.counterpart.getter) irvrvs[role_values] = role_values.index_values(self) end klasses.each do |klass| klass.all_role.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 next if role.fact_type.is_a?(TypeInheritanceFactType) i = send(role.getter) next unless i if counterpart. && 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 rv = i.send(role.counterpart.getter) rv.delete_instance(self, irvrvs[rv]) 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: next if role.fact_type.is_a?(TypeInheritanceFactType) counterpart_instances = send(role.name) counterpart_instances.to_a.each do |counterpart_instance| # These actions deconstruct the RoleValues as we go: if counterpart. && counterpart.mandatory counterpart_instance.retract else counterpart_instance.send(counterpart.setter, nil, false) end end instance_variable_set(role.variable, nil) end end end end |