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
321 322 323 324 325 326 327 328 329 330 |
# File 'lib/familia/features/relationships.rb', line 321 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)
333 334 335 336 337 338 339 340 341 342 343 344 345 346 |
# File 'lib/familia/features/relationships.rb', line 333 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
409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 |
# File 'lib/familia/features/relationships.rb', line 409 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
397 398 399 400 401 402 403 404 405 406 |
# File 'lib/familia/features/relationships.rb', line 397 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
290 291 292 293 294 295 |
# File 'lib/familia/features/relationships.rb', line 290 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
392 393 394 |
# File 'lib/familia/features/relationships.rb', line 392 def redis self.class.dbclient end |
#refresh_relationships! ⇒ Object
Refresh relationship data from Redis (useful after external changes)
369 370 371 372 373 374 375 376 377 378 |
# File 'lib/familia/features/relationships.rb', line 369 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)
381 382 383 384 385 386 387 388 389 |
# File 'lib/familia/features/relationships.rb', line 381 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
298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 |
# File 'lib/familia/features/relationships.rb', line 298 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
268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 |
# File 'lib/familia/features/relationships.rb', line 268 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
349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 |
# File 'lib/familia/features/relationships.rb', line 349 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 |