Module: Familia::Features::Relationships::CollectionOperations

Included in:
ParticipantMethods, ParticipantMethods::Builder, TargetMethods, TargetMethods::Builder
Defined in:
lib/familia/features/relationships/collection_operations.rb

Overview

Shared collection operations for Participation module Provides common methods for working with Horreum-managed DataType collections Used by both ParticipantMethods and TargetMethods to reduce duplication

Instance Method Summary collapse

Instance Method Details

#add_to_collection(collection, item, type:, score: nil, target_class: nil, collection_name: nil) ⇒ Object

Add an item to a collection, handling type-specific operations

Parameters:

  • collection (Familia::DataType)

    The collection to add to

  • item (Object)

    The item to add (must respond to identifier)

  • score (Float, nil) (defaults to: nil)

    Score for sorted sets

  • type (Symbol)

    Collection type



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/familia/features/relationships/collection_operations.rb', line 50

def add_to_collection(collection, item, type:, score: nil, target_class: nil, collection_name: nil)
  case type
  when :sorted_set
    # Ensure score is never nil for sorted sets
    score ||= calculate_item_score(item, target_class, collection_name)
    collection.add(item, score)
  when :list
    # Lists use push/unshift operations
    collection.add(item)
  when :set
    # Sets use simple add
    collection.add(item)
  else
    raise ArgumentError, "Unknown collection type: #{type}"
  end
end

#bulk_add_to_collection(collection, items, type:, target_class: nil, collection_name: nil) ⇒ Object

Bulk add items to a collection using DataType methods

Parameters:

  • collection (Familia::DataType)

    The collection to add to

  • items (Array)

    Array of items to add

  • type (Symbol)

    Collection type



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/familia/features/relationships/collection_operations.rb', line 88

def bulk_add_to_collection(collection, items, type:, target_class: nil, collection_name: nil)
  return if items.empty?

  case type
  when :sorted_set
    # Add items one by one for sorted sets to ensure proper scoring
    items.each do |item|
      score = calculate_item_score(item, target_class, collection_name)
      collection.add(item, score)
    end
  when :set, :list
    # For sets and lists, add items one by one using DataType methods
    items.each do |item|
      collection.add(item)
    end
  else
    raise ArgumentError, "Unknown collection type: #{type}"
  end
end

#ensure_collection_field(target_class, collection_name, type, participant_class: nil) ⇒ Object

Ensure a target class has the specified DataType field defined

When +participant_class+ is provided, the collection is declared with +record_class:+ pointing at the participant class. This is a loading-only hint: it lets +each_record+ hydrate the stored participant identifiers via +load_multi+ (issue #297) WITHOUT changing how the collection deserializes reads. +members+/+member?+/+score+ keep the generic DataType semantics, so adding participation to a collection is transparent to existing readers.

This deliberately differs from +instances+ and +unique_index+, which use +class: + reference: true+ because they also want raw-string read semantics. Participation only needs the loading capability, so it uses the narrower +record_class:+ option and avoids any read-behavior change.

Parameters:

  • target_class (Class)

    The class that should have the collection

  • collection_name (Symbol)

    Name of the collection field

  • type (Symbol)

    Collection type (:sorted_set, :set, :list)

  • participant_class (Class, nil) (defaults to: nil)

    The class whose identifiers the collection stores (the participant). When nil, the collection is declared with no record_class (each_record stays unavailable).



35
36
37
38
39
40
41
42
43
# File 'lib/familia/features/relationships/collection_operations.rb', line 35

def ensure_collection_field(target_class, collection_name, type, participant_class: nil)
  return if target_class.method_defined?(collection_name)

  if participant_class
    target_class.send(type, collection_name, record_class: participant_class)
  else
    target_class.send(type, collection_name)
  end
end

#member_of_collection?(collection, item) ⇒ Boolean

Check if an item is a member of a collection

Parameters:

  • collection (Familia::DataType)

    The collection to check

  • item (Object)

    The item to check (must respond to identifier)

Returns:

  • (Boolean)

    True if item is in collection



80
81
82
# File 'lib/familia/features/relationships/collection_operations.rb', line 80

def member_of_collection?(collection, item)
  collection.member?(item)
end

#remove_from_collection(collection, item, type: nil) ⇒ Object

Remove an item from a collection

Parameters:

  • collection (Familia::DataType)

    The collection to remove from

  • item (Object)

    The item to remove (must respond to identifier)

  • type (Symbol) (defaults to: nil)

    Collection type



71
72
73
74
# File 'lib/familia/features/relationships/collection_operations.rb', line 71

def remove_from_collection(collection, item, type: nil)
  # All collection types support remove/delete
  collection.remove(item)
end