Module: Familia::Features::Relationships::InstanceMethods
- Defined in:
- lib/familia/features/relationships.rb
Instance Method Summary collapse
-
#cleanup_all_relationships! ⇒ Object
Comprehensive cleanup - remove from all relationships.
-
#cleanup_preview ⇒ Object
Dry run for relationship cleanup (preview what would be affected).
-
#cleanup_temp_keys(pattern = 'temp:*', batch_size = 100) ⇒ Object
Instance method wrapper for cleanup_temp_keys.
-
#create_temp_key(base_name, ttl = 300) ⇒ Object
Instance method wrapper for create_temp_key.
-
#destroy! ⇒ Object
Override destroy to handle cascade operations.
-
#identifier ⇒ Object
Get the identifier value for this instance Uses the existing Horreum identifier infrastructure.
-
#identifier=(value) ⇒ Object
Set the identifier value for this instance.
-
#initialize_relationships ⇒ Object
Initialize relationships (called after object creation).
-
#redis ⇒ Object
Direct Redis access for instance methods.
-
#refresh_relationships! ⇒ Object
Refresh relationship data from Redis (useful after external changes).
-
#relationship_snapshot ⇒ Object
Create a snapshot of current relationship state (for debugging).
-
#relationship_status ⇒ Object
Get comprehensive relationship status for this object.
-
#save(update_expiration: true) ⇒ Object
Override save to update relationships automatically.
-
#validate_relationships! ⇒ Object
Validate that this object’s relationships are consistent.
Instance Method Details
#cleanup_all_relationships! ⇒ Object
Comprehensive cleanup - remove from all relationships
322 323 324 325 326 327 328 329 330 331 |
# File 'lib/familia/features/relationships.rb', line 322 def cleanup_all_relationships! # Remove from tracking collections remove_from_all_tracking_collections if respond_to?(:remove_from_all_tracking_collections) # Remove from membership collections remove_from_all_memberships if respond_to?(:remove_from_all_memberships) # Remove from indexes remove_from_all_indexes if respond_to?(:remove_from_all_indexes) end |
#cleanup_preview ⇒ Object
Dry run for relationship cleanup (preview what would be affected)
334 335 336 337 338 339 340 341 342 343 344 345 346 347 |
# File 'lib/familia/features/relationships.rb', line 334 def cleanup_preview preview = { tracking_collections: [], membership_collections: [], index_entries: [] } if respond_to?(:cascade_dry_run) cascade_preview = cascade_dry_run preview.merge!(cascade_preview) end preview end |
#cleanup_temp_keys(pattern = 'temp:*', batch_size = 100) ⇒ Object
Instance method wrapper for cleanup_temp_keys
410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 |
# File 'lib/familia/features/relationships.rb', line 410 def cleanup_temp_keys(pattern = 'temp:*', batch_size = 100) cursor = 0 loop do cursor, keys = redis.scan(cursor, match: pattern, count: batch_size) if keys.any? # Check TTL and remove keys that should have expired keys.each_slice(batch_size) do |key_batch| redis.pipelined do |pipeline| key_batch.each do |key| ttl = redis.ttl(key) pipeline.del(key) if ttl == -1 # Key exists but has no TTL end end end end break if cursor.zero? end end |
#create_temp_key(base_name, ttl = 300) ⇒ Object
Instance method wrapper for create_temp_key
398 399 400 401 402 403 404 405 406 407 |
# File 'lib/familia/features/relationships.rb', line 398 def create_temp_key(base_name, ttl = 300) = Time.now.to_i random_suffix = SecureRandom.hex(3) temp_key = "temp:#{base_name}:#{}:#{random_suffix}" # Set immediate expiry to ensure cleanup even if operation fails redis.expire(temp_key, ttl) temp_key end |
#destroy! ⇒ Object
Override destroy to handle cascade operations
291 292 293 294 295 296 |
# File 'lib/familia/features/relationships.rb', line 291 def destroy! # Execute cascade operations before destroying the object execute_cascade_operations if respond_to?(:execute_cascade_operations) super end |
#identifier ⇒ Object
Get the identifier value for this instance Uses the existing Horreum identifier infrastructure
252 253 254 255 |
# File 'lib/familia/features/relationships.rb', line 252 def identifier id_field = self.class.identifier_field send(id_field) if respond_to?(id_field) end |
#identifier=(value) ⇒ Object
Set the identifier value for this instance
258 259 260 261 |
# File 'lib/familia/features/relationships.rb', line 258 def identifier=(value) id_field = self.class.identifier_field send("#{id_field}=", value) if respond_to?("#{id_field}=") end |
#initialize_relationships ⇒ Object
Initialize relationships (called after object creation)
264 265 266 |
# File 'lib/familia/features/relationships.rb', line 264 def initialize_relationships # This can be overridden by subclasses to set up initial relationships end |
#redis ⇒ Object
Direct Redis access for instance methods
393 394 395 |
# File 'lib/familia/features/relationships.rb', line 393 def redis self.class.dbclient end |
#refresh_relationships! ⇒ Object
Refresh relationship data from Redis (useful after external changes)
370 371 372 373 374 375 376 377 378 379 |
# File 'lib/familia/features/relationships.rb', line 370 def refresh_relationships! # Clear any cached relationship data @relationship_status = nil @tracking_memberships = nil @membership_collections = nil @index_memberships = nil # Reload fresh data relationship_status end |
#relationship_snapshot ⇒ Object
Create a snapshot of current relationship state (for debugging)
382 383 384 385 386 387 388 389 390 |
# File 'lib/familia/features/relationships.rb', line 382 def relationship_snapshot { timestamp: Time.now, identifier: identifier, class: self.class.name, status: relationship_status, redis_keys: } end |
#relationship_status ⇒ Object
Get comprehensive relationship status for this object
299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 |
# File 'lib/familia/features/relationships.rb', line 299 def relationship_status status = { identifier: identifier, tracking_memberships: [], membership_collections: [], index_memberships: [] } # Get tracking memberships if respond_to?(:tracking_collections_membership) status[:tracking_memberships] = tracking_collections_membership end # Get membership collections status[:membership_collections] = membership_collections if respond_to?(:membership_collections) # Get index memberships status[:index_memberships] = indexing_memberships if respond_to?(:indexing_memberships) status end |
#save(update_expiration: true) ⇒ Object
Override save to update relationships automatically
269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 |
# File 'lib/familia/features/relationships.rb', line 269 def save(update_expiration: true) result = super if result # Automatically update all indexes when object is saved if respond_to?(:update_all_indexes) update_all_indexes end # Auto-add to class-level tracking collections if respond_to?(:add_to_class_tracking_collections) add_to_class_tracking_collections end # NOTE: Relationship-specific membership and tracking updates are done explicitly # since we need to know which specific collections this object should be in end result end |
#validate_relationships! ⇒ Object
Validate that this object’s relationships are consistent
350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 |
# File 'lib/familia/features/relationships.rb', line 350 def validate_relationships! errors = [] # Validate identifier exists errors << 'Object identifier is nil' unless identifier # Validate tracking memberships if respond_to?(:tracking_collections_membership) tracking_collections_membership.each do |membership| score = membership[:score] errors << "Invalid score in tracking membership: #{membership}" if score && !score.is_a?(Numeric) end end raise RelationshipError, "Relationship validation failed for #{self}: #{errors.join('; ')}" if errors.any? true end |