activefacts-api 1.9.5 → 1.9.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/activefacts/api/constellation.rb +195 -195
- data/lib/activefacts/api/date.rb +8 -8
- data/lib/activefacts/api/entity.rb +228 -228
- data/lib/activefacts/api/exceptions.rb +13 -13
- data/lib/activefacts/api/fact_type.rb +5 -5
- data/lib/activefacts/api/guid.rb +9 -9
- data/lib/activefacts/api/instance.rb +93 -88
- data/lib/activefacts/api/instance_index.rb +52 -52
- data/lib/activefacts/api/numeric.rb +14 -14
- data/lib/activefacts/api/object_type.rb +231 -231
- data/lib/activefacts/api/role_values.rb +68 -68
- data/lib/activefacts/api/standard_types.rb +1 -1
- data/lib/activefacts/api/version.rb +1 -1
- data/lib/activefacts/api/vocabulary.rb +13 -7
- metadata +1 -1
@@ -98,14 +98,14 @@ module ActiveFacts
|
|
98
98
|
def identifying_role_values(constellation, args)
|
99
99
|
arg_hash = args[-1].is_a?(Hash) ? args.pop : {}
|
100
100
|
n =
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
101
|
+
case
|
102
|
+
when args == [:new] # A new object has no identifying_role_values
|
103
|
+
:new
|
104
|
+
when args.size == 1 && args[0].is_a?(AutoCounter)
|
105
|
+
args[0] # An AutoCounter is its own key
|
106
|
+
else
|
107
|
+
new(*args)
|
108
|
+
end
|
109
109
|
args.replace([arg_hash])
|
110
110
|
n
|
111
111
|
end
|
@@ -125,10 +125,10 @@ class AutoCounter
|
|
125
125
|
@place_holder_number = (@@place_holder+=1)
|
126
126
|
when AutoCounter
|
127
127
|
if i.defined?
|
128
|
-
|
128
|
+
@value = i.to_i
|
129
129
|
else
|
130
|
-
|
131
|
-
|
130
|
+
@place_holder_number = i.place_holder_number
|
131
|
+
@value = nil
|
132
132
|
end
|
133
133
|
else
|
134
134
|
@place_holder_number = @value = i.to_i;
|
@@ -191,12 +191,12 @@ class AutoCounter
|
|
191
191
|
to_s.eql?(o.to_s)
|
192
192
|
end
|
193
193
|
|
194
|
-
def <=>(o)
|
194
|
+
def <=>(o) #:nodoc:
|
195
195
|
if self.defined? && !o == [] && o.defined?
|
196
196
|
if (c = (self.class <=> o.class.name)) != 0
|
197
|
-
|
197
|
+
return c
|
198
198
|
else
|
199
|
-
|
199
|
+
return to_i <=> o.to_i
|
200
200
|
end
|
201
201
|
else
|
202
202
|
to_s.<=>(o.to_s)
|
@@ -50,25 +50,25 @@ module ActiveFacts
|
|
50
50
|
end
|
51
51
|
|
52
52
|
def add_role(role)
|
53
|
-
|
54
|
-
|
53
|
+
all_role[role.name] = role
|
54
|
+
@all_role_transitive = nil # Undo the caching
|
55
55
|
end
|
56
56
|
|
57
57
|
def all_role_transitive
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
58
|
+
return @all_role_transitive if @all_role_transitive
|
59
|
+
@all_role_transitive = all_role.dup
|
60
|
+
supertypes_transitive.each do |klass|
|
61
|
+
@all_role_transitive.merge!(klass.all_role)
|
62
|
+
end
|
63
|
+
@all_role_transitive
|
64
64
|
end
|
65
65
|
|
66
66
|
# Define a unary fact type attached to this object_type; in essence, a boolean attribute.
|
67
67
|
#
|
68
68
|
# Example: maybe :is_ceo
|
69
69
|
def maybe(role_name, options = {})
|
70
|
-
|
71
|
-
|
70
|
+
raise UnrecognisedOptionsException.new("role", role_name, options.keys) unless options.empty?
|
71
|
+
fact_type = FactType.new
|
72
72
|
realise_role(Role.new(fact_type, self, role_name, false, true))
|
73
73
|
end
|
74
74
|
|
@@ -110,11 +110,11 @@ module ActiveFacts
|
|
110
110
|
case type
|
111
111
|
when :has_one
|
112
112
|
if identifying_role_names.size == 1
|
113
|
-
|
113
|
+
raise InvalidIdentificationException.new(self, role, true)
|
114
114
|
end
|
115
115
|
when :one_to_one
|
116
116
|
if identifying_role_names.size > 1
|
117
|
-
|
117
|
+
raise InvalidIdentificationException.new(self, role, false)
|
118
118
|
end
|
119
119
|
end
|
120
120
|
end
|
@@ -127,48 +127,48 @@ module ActiveFacts
|
|
127
127
|
# Without parameters, it returns the array of ObjectType supertypes
|
128
128
|
# (one by Ruby inheritance, any others as defined using this method)
|
129
129
|
def supertypes(*object_types)
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
130
|
+
@supertypes ||= []
|
131
|
+
all_supertypes = supertypes_transitive
|
132
|
+
object_types.each do |object_type|
|
133
|
+
next if all_supertypes.include? object_type
|
134
|
+
supertype =
|
135
|
+
case object_type
|
136
|
+
when Class
|
137
|
+
object_type
|
138
|
+
when Symbol
|
139
|
+
# No late binding here:
|
140
|
+
(object_type = vocabulary.const_get(object_type.to_s.camelcase))
|
141
|
+
else
|
142
|
+
raise InvalidSupertypeException.new("Illegal supertype #{object_type.inspect} for #{self.class.basename}")
|
143
|
+
end
|
144
|
+
unless supertype.respond_to?(:vocabulary) and supertype.vocabulary == self.vocabulary
|
145
|
+
raise InvalidSupertypeException.new("#{supertype.name} must be an object type in #{vocabulary.name}")
|
146
|
+
end
|
147
|
+
|
148
|
+
if is_entity_type != supertype.is_entity_type
|
149
|
+
raise InvalidSupertypeException.new("#{self} < #{supertype}: A value type may not be a supertype of an entity type, and vice versa")
|
150
|
+
end
|
151
|
+
|
152
|
+
TypeInheritanceFactType.new(supertype, self)
|
153
|
+
@supertypes << supertype
|
154
|
+
|
155
|
+
# Realise the roles (create accessors) of this supertype.
|
156
|
+
realise_supertypes(object_type, all_supertypes)
|
157
|
+
end
|
158
|
+
[(superclass.respond_to?(:vocabulary) ? superclass : nil), *@supertypes].compact
|
159
159
|
end
|
160
160
|
|
161
161
|
# Return the array of all ObjectType supertypes, transitively.
|
162
162
|
def supertypes_transitive
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
163
|
+
supertypes = []
|
164
|
+
v = superclass.respond_to?(:vocabulary) ? superclass.vocabulary : nil
|
165
|
+
supertypes << superclass if v.kind_of?(Module)
|
166
|
+
supertypes += (@supertypes ||= [])
|
167
|
+
sts = supertypes.inject([]) do |a, t|
|
168
|
+
next if a.include?(t)
|
169
|
+
a += [t] + t.supertypes_transitive
|
170
|
+
end.uniq
|
171
|
+
sts # The local variable unconfuses rcov
|
172
172
|
end
|
173
173
|
|
174
174
|
def subtypes
|
@@ -176,7 +176,7 @@ module ActiveFacts
|
|
176
176
|
end
|
177
177
|
|
178
178
|
def subtypes_transitive
|
179
|
-
|
179
|
+
(subtypes+subtypes.map(&:subtypes_transitive)).flatten.uniq
|
180
180
|
end
|
181
181
|
|
182
182
|
# Every new role added or inherited comes through here:
|
@@ -218,210 +218,210 @@ module ActiveFacts
|
|
218
218
|
|
219
219
|
# Shared code for both kinds of binary fact type (has_one and one_to_one)
|
220
220
|
def define_binary_fact_type(one_to_one, role_name, related, mandatory, related_role_name, restrict)
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
221
|
+
if r = all_role_transitive[role_name]
|
222
|
+
# Allow a one-to-one to be defined identically from both ends:
|
223
|
+
if one_to_one and
|
224
|
+
r.unique and
|
225
|
+
!r.unary? and
|
226
|
+
r.object_type == self and # Cannot be an inherited role
|
227
|
+
r.counterpart.unique and
|
228
|
+
related == r.counterpart.object_type
|
229
|
+
# and related_role_name == r.counterpart.name
|
230
|
+
# REVISIT: Cannot add a value constraint here yet
|
231
|
+
r.make_mandatory if mandatory && !r.mandatory # This was impossible
|
232
|
+
return
|
233
|
+
end
|
234
|
+
|
235
|
+
raise DuplicateRoleException.new("#{name} cannot have more than one role named #{role_name}")
|
236
|
+
end
|
237
|
+
fact_type = FactType.new
|
238
238
|
role = Role.new(fact_type, self, role_name, mandatory, true, restrict)
|
239
239
|
|
240
240
|
# There may be a forward reference here where role_name is a Symbol,
|
241
241
|
# and the block runs later when that Symbol is bound to the object_type.
|
242
242
|
when_bound(related, self, role_name, related_role_name) do |target, definer, role_name, related_role_name|
|
243
|
-
|
243
|
+
counterpart = Role.new(fact_type, target, related_role_name, false, one_to_one)
|
244
244
|
realise_role(role)
|
245
245
|
target.realise_role(counterpart)
|
246
246
|
end
|
247
247
|
end
|
248
248
|
|
249
249
|
def define_unary_role_accessor(role)
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
250
|
+
define_method role.setter do |value, options = 0|
|
251
|
+
# Normalise the value to be assigned (nil, false, true):
|
252
|
+
value = case value
|
253
|
+
when nil; nil
|
254
|
+
when false; false
|
255
|
+
else true
|
256
|
+
end
|
257
|
+
|
258
|
+
old = instance_variable_get(role.variable)
|
259
|
+
return value if old == value
|
260
|
+
|
261
|
+
if role.is_identifying and (options&CHECKED_IDENTIFYING_ROLE) == 0
|
262
|
+
check_identification_change_legality(role, value)
|
263
|
+
impacts = analyse_impacts(role)
|
264
|
+
end
|
265
|
+
|
266
|
+
instance_variable_set(role.variable, value)
|
267
|
+
|
268
|
+
if impacts
|
269
|
+
@constellation.when_admitted do
|
270
|
+
# REVISIT: Consider whether we want to provide a way to find all instances
|
271
|
+
# playing/not playing this boolean role, analogous to true.all_thing_as_role_name...
|
272
|
+
apply_impacts(impacts) # Propagate dependent key changes
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
unless @constellation.loggers.empty? or options != 0
|
277
|
+
sv = self.identifying_role_values(role.object_type)
|
278
|
+
@constellation.loggers.each{|l| l.call(:assign, role.object_type, role, sv, old, value) }
|
279
|
+
end
|
280
|
+
|
281
|
+
value
|
282
|
+
end
|
283
283
|
define_single_role_getter(role)
|
284
284
|
end
|
285
285
|
|
286
286
|
def define_single_role_getter(role)
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
287
|
+
define_method role.getter do |*a|
|
288
|
+
if a.size > 0
|
289
|
+
raise ArgumentError.new("wrong number of arguments (#{a.size} for 0)")
|
290
|
+
end
|
291
|
+
instance_variable_get(role.variable)
|
292
|
+
end
|
293
293
|
end
|
294
294
|
|
295
295
|
def define_one_to_one_accessor(role)
|
296
296
|
define_single_role_getter(role)
|
297
297
|
|
298
|
-
|
299
|
-
|
300
|
-
|
298
|
+
# What I want is the following, but it doesn't work in Ruby 1.8
|
299
|
+
define_method role.setter do |value, options = 0|
|
300
|
+
role_var = role.variable
|
301
301
|
|
302
|
-
|
303
|
-
|
304
|
-
|
302
|
+
# Get old value, and jump out early if it's unchanged:
|
303
|
+
old = instance_variable_get(role_var)
|
304
|
+
return value if old == value
|
305
305
|
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
306
|
+
# assert a new instance for the role value if necessary
|
307
|
+
if value and o = role.counterpart.object_type and (!value.is_a?(o) || value.constellation != @constellation)
|
308
|
+
value = @constellation.assert(o, *Array(value))
|
309
|
+
return value if old == value
|
310
|
+
end
|
311
311
|
|
312
|
-
|
313
|
-
|
314
|
-
|
312
|
+
# We're changing this object's key. Check legality and prepare to propagate
|
313
|
+
if role.is_identifying and (options&CHECKED_IDENTIFYING_ROLE) == 0
|
314
|
+
check_identification_change_legality(role, value)
|
315
315
|
|
316
|
-
|
317
|
-
|
318
|
-
|
316
|
+
# puts "Starting to analyse impact of changing 1-1 #{role.inspect} to #{value.inspect}"
|
317
|
+
impacts = analyse_impacts(role)
|
318
|
+
end
|
319
319
|
|
320
|
-
|
320
|
+
instance_variable_set(role_var, value)
|
321
321
|
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
322
|
+
# Remove self from the old counterpart:
|
323
|
+
if old and (options&SKIP_MUTUAL_PROPAGATION) == 0
|
324
|
+
old.send(role.counterpart.setter, nil, options|SKIP_MUTUAL_PROPAGATION)
|
325
|
+
end
|
326
326
|
|
327
|
-
|
328
|
-
|
329
|
-
|
327
|
+
@constellation.when_admitted do
|
328
|
+
# Assign self to the new counterpart
|
329
|
+
value.send(role.counterpart.setter, self, options) if value && (options&SKIP_MUTUAL_PROPAGATION) == 0
|
330
330
|
|
331
|
-
|
332
|
-
|
331
|
+
apply_impacts(impacts) if impacts # Propagate dependent key changes
|
332
|
+
end
|
333
333
|
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
334
|
+
unless @constellation.loggers.empty? or options != 0
|
335
|
+
sv = self.identifying_role_values(role.object_type)
|
336
|
+
ov = old.identifying_role_values
|
337
|
+
nv = value.identifying_role_values
|
338
|
+
@constellation.loggers.each{|l| l.call(:assign, role.object_type, role, sv, ov, nv) }
|
339
|
+
end
|
340
340
|
|
341
|
-
|
342
|
-
|
341
|
+
value
|
342
|
+
end
|
343
343
|
end
|
344
344
|
|
345
345
|
def define_one_to_many_accessor(role)
|
346
346
|
define_single_role_getter(role)
|
347
347
|
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
348
|
+
define_method role.setter do |value, options = 0|
|
349
|
+
role_var = role.variable
|
350
|
+
|
351
|
+
# Get old value, and jump out early if it's unchanged:
|
352
|
+
old = instance_variable_get(role_var)
|
353
|
+
return value if old == value
|
354
|
+
|
355
|
+
# assert a new instance for the role value if necessary
|
356
|
+
if value and o = role.counterpart.object_type and (!value.is_a?(o) || value.constellation != @constellation)
|
357
|
+
value = @constellation.assert(o, *Array(value))
|
358
|
+
return value if old == value # Occurs when another instance having the same value is assigned
|
359
|
+
end
|
360
|
+
|
361
|
+
if role.is_identifying and (options&CHECKED_IDENTIFYING_ROLE) == 0
|
362
|
+
# We're changing this object's key. Check legality and prepare to propagate
|
363
|
+
check_identification_change_legality(role, value)
|
364
|
+
|
365
|
+
# puts "Starting to analyse impact of changing 1-N #{role.inspect} to #{value.inspect}"
|
366
|
+
impacts = analyse_impacts(role)
|
367
|
+
end
|
368
|
+
|
369
|
+
if old and (options&SKIP_MUTUAL_PROPAGATION) == 0
|
370
|
+
old_role_values = old.send(getter = role.counterpart.getter)
|
371
|
+
old_key = old_role_values.index_values(self)
|
372
|
+
end
|
373
|
+
|
374
|
+
instance_variable_set(role_var, value)
|
375
|
+
|
376
|
+
# Remove "self" from the old counterpart:
|
377
|
+
if old_key
|
378
|
+
old_role_values.delete_instance(self, old_key)
|
379
|
+
if (old_role_values.empty? && !old.class.is_entity_type)
|
380
|
+
old.retract if old.plays_no_role
|
381
|
+
end
|
382
|
+
end
|
383
|
+
|
384
|
+
@constellation.when_admitted do
|
385
|
+
# Add "self" into the counterpart
|
386
|
+
if value
|
387
|
+
rv = value.send(getter ||= role.counterpart.getter)
|
388
|
+
rv.add_instance(self, identifying_role_values(role.object_type))
|
389
|
+
end
|
390
|
+
|
391
|
+
apply_impacts(impacts) if impacts # Propagate dependent key changes
|
392
|
+
end
|
393
|
+
|
394
|
+
unless @constellation.loggers.empty? or options != 0
|
395
|
+
sv = self.identifying_role_values(role.object_type)
|
396
|
+
ov = old.identifying_role_values
|
397
|
+
nv = value.identifying_role_values
|
398
|
+
@constellation.loggers.each{|l| l.call(:assign, role.object_type, role, sv, ov, nv) }
|
399
|
+
end
|
400
|
+
|
401
|
+
value
|
402
|
+
end
|
403
403
|
end
|
404
404
|
|
405
405
|
def define_many_to_one_accessor(role)
|
406
406
|
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
407
|
+
define_method role.getter do |*keys|
|
408
|
+
role_var = role.variable
|
409
|
+
role_values =
|
410
|
+
instance_variable_get(role_var) || begin
|
411
|
+
|
412
|
+
# Decide which roles this index will use (exclude the counterpart role from the id)
|
413
|
+
if role.counterpart and
|
414
|
+
counterpart = role.counterpart.object_type and
|
415
|
+
counterpart.is_entity_type
|
416
|
+
excluded_role = counterpart.identifying_roles.index(role.counterpart)
|
417
|
+
else
|
418
|
+
index_roles = nil
|
419
|
+
end
|
420
|
+
|
421
|
+
instance_variable_set(role_var, RoleValues.new(role.counterpart, excluded_role))
|
422
|
+
end
|
423
|
+
# Look up a value by the key provided, or return the whole collection
|
424
|
+
keys.size == 0 ? role_values : role_values.[](*keys)
|
425
425
|
end
|
426
426
|
end
|
427
427
|
|
@@ -455,13 +455,13 @@ module ActiveFacts
|
|
455
455
|
# The counterpart class (type) might be forward-referenced, so handle a Symbol/String instead of a Class.
|
456
456
|
specified_class = options.delete(:class)
|
457
457
|
case specified_class
|
458
|
-
when Class
|
458
|
+
when Class # Preferred and most common case
|
459
459
|
counterpart_type_or_name = specified_class
|
460
460
|
counterpart_type_default_role_name = specified_class.basename.to_s.snakecase
|
461
|
-
when Symbol, String
|
461
|
+
when Symbol, String # Use this to handle forward references
|
462
462
|
counterpart_type_or_name = specified_class.to_s.camelcase
|
463
463
|
counterpart_type_default_role_name = specified_class.to_s.snakecase
|
464
|
-
when nil
|
464
|
+
when nil # No :class provided, assume it matches the role_name
|
465
465
|
counterpart_type_or_name = role_name.to_s.camelcase
|
466
466
|
counterpart_type_default_role_name = role_name.to_s
|
467
467
|
else
|
@@ -470,11 +470,11 @@ module ActiveFacts
|
|
470
470
|
|
471
471
|
# resolve the Symbol or String to a Class now if possible:
|
472
472
|
unless counterpart_type_or_name.is_a?(Class)
|
473
|
-
|
474
|
-
|
475
|
-
|
473
|
+
resolved = vocabulary.object_type(counterpart_type_or_name)
|
474
|
+
counterpart_type_or_name = resolved if resolved
|
475
|
+
end
|
476
476
|
|
477
|
-
|
477
|
+
# If the role is played by a known Class, check it's in the same vocabulary:
|
478
478
|
if counterpart_type_or_name.is_a?(Class)
|
479
479
|
unless counterpart_type_or_name.respond_to?(:vocabulary) and counterpart_type_or_name.vocabulary == self.vocabulary
|
480
480
|
raise CrossVocabularyRoleException.new(counterpart_type_or_name, vocabulary)
|
@@ -491,15 +491,15 @@ module ActiveFacts
|
|
491
491
|
default_role_name = self.basename.snakecase # Default name of counterpart role (played by self)
|
492
492
|
counterpart_role_name = options.delete(:counterpart)
|
493
493
|
counterpart_role_name = counterpart_role_name.to_s if counterpart_role_name
|
494
|
-
|
494
|
+
counterpart_role_name ||= default_role_name
|
495
495
|
|
496
|
-
|
496
|
+
raise UnrecognisedOptionsException.new("role", role_name, options.keys) unless options.empty?
|
497
497
|
|
498
498
|
# If you have a role "supervisor" and a sub-class "Supervisor", this'll bitch.
|
499
|
-
if !specified_class and
|
500
|
-
|
501
|
-
|
502
|
-
|
499
|
+
if !specified_class and # No specified :class was provided
|
500
|
+
counterpart_type_or_name.is_a?(Class) and
|
501
|
+
(indicated = vocabulary.object_type(role_name)) and
|
502
|
+
indicated != counterpart_type_or_name
|
503
503
|
raise "Role name #{role_name} indicates a different counterpart object_type #{indicated} than specified"
|
504
504
|
end
|
505
505
|
|
@@ -511,7 +511,7 @@ module ActiveFacts
|
|
511
511
|
(one_to_one ? "" : "all_") +
|
512
512
|
counterpart_role_name
|
513
513
|
if counterpart_role_name == default_role_name and
|
514
|
-
|
514
|
+
role_name.to_s != counterpart_type_default_role_name
|
515
515
|
other_role_method += "_as_#{role_name}"
|
516
516
|
end
|
517
517
|
|
@@ -519,7 +519,7 @@ module ActiveFacts
|
|
519
519
|
counterpart_type_or_name,
|
520
520
|
mandatory,
|
521
521
|
other_role_method.to_sym,
|
522
|
-
|
522
|
+
restrict
|
523
523
|
]
|
524
524
|
end
|
525
525
|
|