Module: Familia::Features::Relationships

Defined in:
lib/familia/features/relationships.rb,
lib/familia/features/relationships/indexing.rb,
lib/familia/features/relationships/participation.rb,
lib/familia/features/relationships/score_encoding.rb,
lib/familia/features/relationships/collection_operations.rb,
lib/familia/features/relationships/indexing_relationship.rb,
lib/familia/features/relationships/participation_membership.rb,
lib/familia/features/relationships/participation_relationship.rb,
lib/familia/features/relationships/indexing/rebuild_strategies.rb,
lib/familia/features/relationships/participation/target_methods.rb,
lib/familia/features/relationships/indexing/multi_index_generators.rb,
lib/familia/features/relationships/participation/staged_operations.rb,
lib/familia/features/relationships/indexing/unique_index_generators.rb,
lib/familia/features/relationships/participation/participant_methods.rb,
lib/familia/features/relationships/participation/through_model_operations.rb

Overview

Unified Relationships feature for Familia v2

This feature merges the functionality of relatable_objects and relationships into a single, Valkey/Redis-native implementation that embraces the "where does this appear?" philosophy rather than "who owns this?".

Examples:

Basic usage

class Domain < Familia::Horreum

  identifier_field :domain_id

  field :domain_id
  field :display_name
  field :created_at
  field :permission_bits

  feature :relationships

  # Multi-presence participation with score encoding
  participates_in Customer, :domains,
                  score: -> { permission_encode(created_at, permission_bits) }
  participates_in Team, :domains, score: :added_at
  participates_in Organization, :all_domains, score: :created_at

  # O(1) lookups with Valkey/Redis hashes
  indexed_by :display_name, :domain_index, target: Customer

  # Participation with bidirectional control (no method collisions)
  participates_in Customer, :domains
  participates_in Team, :domains, generate_participant_methods: false
  participates_in Organization, :domains, type: :set
end

Generated methods (collision-free)

# Participation methods
Customer.domains                    # => Familia::SortedSet
Customer.add_domain(domain, score)  # Add to customer's domains
domain.in_customer_domains?(customer) # Check membership

# Indexing methods
Customer.find_by_display_name(name) # O(1) lookup

# Bidirectional methods (collision-free naming)
domain.add_to_customer_domains(customer)  # Specific collection
domain.add_to_team_domains(team)          # Different collection
domain.in_customer_domains?(customer)     # Check specific membership

Score encoding for permissions

# Encode permission in score
score = domain.permission_encode(Familia.now, :write)
# => 1704067200.004 (timestamp + permission bits)

# Decode permission from score
decoded = domain.permission_decode(score)
# => { timestamp: 1704067200, permissions: 4, permission_list: [:write] }

# Query with permission filtering
Customer.domains_with_permission(:read)

Multi-collection operations

# Atomic updates across multiple collections
domain.update_multiple_presence([
  { key: "customer:123:domains", score: current_score },
  { key: "team:456:domains", score: permission_encode(Familia.now, :read) }
], :add, domain.identifier)

# UnsortedSet operations on collections
accessible = Domain.union_collections([
  { owner: customer, collection: :domains },
  { owner: team, collection: :domains }
], min_permission: :read)

Defined Under Namespace

Modules: CollectionOperations, Indexing, ModelClassMethods, ModelInstanceMethods, ParticipantMethods, Participation, ScoreEncoding, TargetMethods Classes: CascadeError, IndexingRelationship, InvalidIdentifierError, InvalidScoreError, ParticipationMembership, ParticipationRelationship, RelationshipError

Class Method Summary collapse

Class Method Details

.included(base) ⇒ Object

Feature initialization



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

def self.included(base)
  Familia.debug "[#{base}] Relationships included"
  base.extend ModelClassMethods
  base.include ModelInstanceMethods

  # Include all relationship submodules and their class methods
  base.include ScoreEncoding

  base.include Participation
  base.extend Participation::ModelClassMethods

  base.include Indexing
  base.extend Indexing::ModelClassMethods
end