Module: ActiveFacts::API::Entity::ClassMethods
- Includes:
- Instance::ClassMethods
- Defined in:
- lib/activefacts/api/entity.rb
Overview
All classes that become Entity types receive the methods of this class as class methods:
Instance Method Summary collapse
-
#assert_instance(constellation, args) ⇒ Object
:nodoc:.
-
#identifying_role_names ⇒ Object
Return the array of Role objects that define the identifying relationships of this Entity type:.
-
#identifying_role_values(*args) ⇒ Object
Convert the passed arguments into an array of Instance objects that can identify an instance of this Entity type:.
-
#index_instance(instance, key = nil, key_roles = nil) ⇒ Object
:nodoc:.
-
#inherited(other) ⇒ Object
:nodoc:.
-
#initialise_entity_type(*args) ⇒ Object
A concept that isn’t a ValueType must have an identification scheme, which is a list of roles it plays.
-
#verbalise ⇒ Object
verbalise this concept.
Methods included from Concept
#__absorb, #columns, #has_one, #is_a?, #is_table, #maybe, #one_to_one, #realise_role, #roles, #subtypes, #supertypes, #supertypes_transitive, #table, #vocabulary
Instance Method Details
#assert_instance(constellation, args) ⇒ Object
:nodoc:
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 |
# File 'lib/activefacts/api/entity.rb', line 146 def assert_instance(constellation, args) #:nodoc: # Build the key for this instance from the args # The key of an instance is the value or array of keys of the identifying values. # The key values aren't necessarily present in the constellation, even after this. key = (*args) # Find and return an existing instance matching this key instances = constellation.instances[self] # All instances of this class in this constellation instance = instances[key] # DEBUG: puts "assert #{self.basename} #{key.inspect} #{instance ? "exists" : "new"}" return instance, key if instance # A matching instance of this class # Now construct each of this object's identifying roles ir = args, arg_hash = ActiveFacts::extract_hash_args(ir, args) role_values = ir.map{|role_sym| roles(role_sym)}.zip(args) key = [] # Gather the actual key (AutoCounters are special) values = role_values.map do |role, arg| if !arg value = role_key = nil # No value elsif !role.counterpart value = role_key = !!arg # Unary elsif arg.is_a?(role.counterpart_concept) # REVISIT: or a secondary supertype arg = arg.__getobj__ if RoleProxy === arg raise "Connecting values across constellations" unless arg.constellation == constellation value, role_key = arg, arg. else value, role_key = role.counterpart_concept.assert_instance(constellation, Array(arg)) end key << role_key value end values << arg_hash if arg_hash and !arg_hash.empty? #puts "Creating new #{basename} using #{values.inspect}" instance = new(*values) # Make the new entity instance a member of this constellation: instance.constellation = constellation return *index_instance(instance, key, ir) end |
#identifying_role_names ⇒ Object
Return the array of Role objects that define the identifying relationships of this Entity type:
108 109 110 |
# File 'lib/activefacts/api/entity.rb', line 108 def @identifying_role_names ||= [] end |
#identifying_role_values(*args) ⇒ Object
Convert the passed arguments into an array of Instance objects that can identify an instance of this Entity type:
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 138 139 140 141 142 143 144 |
# File 'lib/activefacts/api/entity.rb', line 113 def (*args) #puts "Getting identifying role values #{identifying_role_names.inspect} of #{basename} using #{args.inspect}" # If the single arg is an instance of the correct class or a subclass, # use the instance's identifying_role_values if (args.size == 1 and (arg = args[0]).is_a?(self)) # REVISIT: or a secondary supertype arg = arg.__getobj__ if RoleProxy === arg return arg. end ir = args, arg_hash = ActiveFacts::extract_hash_args(ir, args) if args.size < ir.size raise "#{basename} requires all identifying values, you're missing #{ir[args.size..-1].map(&:to_sym)*', '}" elsif args.size > ir.size raise "#{basename} requires all identifying values, you have #{args.size-ir.size} extras #{args[ir.size..-1].map(&:inspect)*', '}" end role_args = ir.map{|role_sym| roles(role_sym)}.zip(args) role_args.map do |role, arg| #puts "Getting identifying_role_value for #{role.counterpart_concept.basename} using #{arg.inspect}" next nil unless arg next !!arg unless role.counterpart # Unary arg = arg.__getobj__ if RoleProxy === arg if arg.is_a?(role.counterpart_concept) # REVISIT: or a secondary supertype # Note that with a secondary supertype, it must still return the values of these identifying_role_names next arg. end role.counterpart_concept.(*arg) end end |
#index_instance(instance, key = nil, key_roles = nil) ⇒ Object
:nodoc:
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 |
# File 'lib/activefacts/api/entity.rb', line 188 def index_instance(instance, key = nil, key_roles = nil) #:nodoc: # Derive a new key if we didn't receive one or if the roles are different: unless key && key_roles && key_roles == key = (key_roles = ).map do |role_name| instance.send role_name end end # Index the instance for this class in the constellation instances = instance.constellation.instances[self] instances[key] = instance # DEBUG: puts "indexing entity #{basename} using #{key.inspect} in #{constellation.object_id}" # Index the instance for each supertype: supertypes.each do |supertype| supertype.index_instance(instance, key, key_roles) end return instance, key end |
#inherited(other) ⇒ Object
:nodoc:
220 221 222 223 224 225 |
# File 'lib/activefacts/api/entity.rb', line 220 def inherited(other) #:nodoc: other.identified_by * subtypes << other unless subtypes.include? other #puts "#{self.name} inherited by #{other.name}" vocabulary.add_concept(other) end |
#initialise_entity_type(*args) ⇒ Object
A concept that isn’t a ValueType must have an identification scheme, which is a list of roles it plays. The identification scheme may be inherited from a superclass.
212 213 214 215 216 217 218 |
# File 'lib/activefacts/api/entity.rb', line 212 def initialise_entity_type(*args) #:nodoc: #puts "Initialising entity type #{self} using #{args.inspect}" @identifying_role_names = superclass. if superclass.respond_to?(:identifying_role_names) # REVISIT: @identifying_role_names here are the symbols passed in, not the Role objects we should use. # We'd need late binding to use Role objects... @identifying_role_names = args if args.size > 0 || !@identifying_role_names end |
#verbalise ⇒ Object
verbalise this concept
228 229 230 |
# File 'lib/activefacts/api/entity.rb', line 228 def verbalise "#{basename} is identified by #{.map{|role_sym| role_sym.to_s.camelcase(true)}*" and "};" end |