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.
-
#validate_relationships! ⇒ Object
Validate that this object’s relationships are consistent.
Instance Method Details
#cleanup_all_relationships! ⇒ Object
Comprehensive cleanup - remove from all relationships
314 315 316 317 318 319 320 321 322 323 |
# File 'lib/familia/features/relationships.rb', line 314 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)
326 327 328 329 330 331 332 333 334 335 336 337 338 339 |
# File 'lib/familia/features/relationships.rb', line 326 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
402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 |
# File 'lib/familia/features/relationships.rb', line 402 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
390 391 392 393 394 395 396 397 398 399 |
# File 'lib/familia/features/relationships.rb', line 390 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
283 284 285 286 287 288 |
# File 'lib/familia/features/relationships.rb', line 283 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
251 252 253 254 |
# File 'lib/familia/features/relationships.rb', line 251 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
257 258 259 260 |
# File 'lib/familia/features/relationships.rb', line 257 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)
263 264 265 |
# File 'lib/familia/features/relationships.rb', line 263 def initialize_relationships # This can be overridden by subclasses to set up initial relationships end |
#redis ⇒ Object
Direct Redis access for instance methods
385 386 387 |
# File 'lib/familia/features/relationships.rb', line 385 def redis self.class.dbclient end |
#refresh_relationships! ⇒ Object
Refresh relationship data from Redis (useful after external changes)
362 363 364 365 366 367 368 369 370 371 |
# File 'lib/familia/features/relationships.rb', line 362 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)
374 375 376 377 378 379 380 381 382 |
# File 'lib/familia/features/relationships.rb', line 374 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
291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 |
# File 'lib/familia/features/relationships.rb', line 291 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
268 269 270 271 272 273 274 275 276 277 278 279 280 |
# File 'lib/familia/features/relationships.rb', line 268 def save(update_expiration: true) result = super if result && respond_to?(:update_all_indexes) # Update all indexes with current field values update_all_indexes # NOTE: Tracking and membership updates are typically 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
342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 |
# File 'lib/familia/features/relationships.rb', line 342 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 |