Module: Familia::Features::Relationships::ParticipantMethods::Builder
- Extended by:
- CollectionOperations
- Defined in:
- lib/familia/features/relationships/participation/participant_methods.rb
Overview
Visual Guide for methods added to PARTICIPANT instances:
When Domain calls: participates_in Customer, :domains
Domain instances (PARTICIPANT) get these methods: ├── in_customer_domains?(customer) # Check if I'm in this customer's domains ├── add_to_customer_domains(customer, score) # Add myself to customer's domains ├── remove_from_customer_domains(customer) # Remove myself from customer's domains ├── score_in_customer_domains(customer) # Get my score (sorted_set only) ├── update_score_in_customer_domains(customer) # Update my score (sorted_set only) └── position_in_customer_domains(customer) # Get my position (list only)
Class Method Summary collapse
-
.build(participant_class, target_class_name, collection_name, type) ⇒ Object
Build all participant methods for a participation relationship.
-
.build_add_to_target(participant_class, target_name, collection_name, type) ⇒ Object
Build method to add self to target's collection Creates: domain.add_to_customer_domains(customer, score).
-
.build_membership_check(participant_class, target_name, collection_name, _type) ⇒ Object
Build method to check membership in target's collection Creates: domain.in_customer_domains?(customer).
-
.build_position_method(participant_class, target_name, collection_name) ⇒ Object
Build position method for lists Creates: domain.position_in_customer_domains(customer).
-
.build_remove_from_target(participant_class, target_name, collection_name, type) ⇒ Object
Build method to remove self from target's collection Creates: domain.remove_from_customer_domains(customer).
-
.build_score_methods(participant_class, target_name, collection_name) ⇒ Object
Build score-related methods for sorted sets Creates: domain.score_in_customer_domains(customer) domain.update_score_in_customer_domains(customer, new_score).
Methods included from CollectionOperations
add_to_collection, bulk_add_to_collection, ensure_collection_field, member_of_collection?, remove_from_collection
Class Method Details
.build(participant_class, target_class_name, collection_name, type) ⇒ Object
Build all participant methods for a participation relationship
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/familia/features/relationships/participation/participant_methods.rb', line 37 def self.build(participant_class, target_class_name, collection_name, type) # Convert to snake_case once for consistency (target_class_name is PascalCase) target_name = target_class_name.to_s.snake_case # Core participant methods build_membership_check(participant_class, target_name, collection_name, type) build_add_to_target(participant_class, target_name, collection_name, type) build_remove_from_target(participant_class, target_name, collection_name, type) # Type-specific methods case type when :sorted_set build_score_methods(participant_class, target_name, collection_name) when :list build_position_method(participant_class, target_name, collection_name) end end |
.build_add_to_target(participant_class, target_name, collection_name, type) ⇒ Object
Build method to add self to target's collection Creates: domain.add_to_customer_domains(customer, score)
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/familia/features/relationships/participation/participant_methods.rb', line 71 def self.build_add_to_target(participant_class, target_name, collection_name, type) method_name = "add_to_#{target_name}_#{collection_name}" participant_class.define_method(method_name) do |target_instance, score = nil| return unless target_instance&.identifier # Use Horreum's DataType accessor instead of manual creation collection = target_instance.send(collection_name) # Calculate score if needed and not provided if type == :sorted_set && score.nil? score = calculate_participation_score(target_instance.class, collection_name) end # Use transaction for atomicity between collection add and reverse index tracking # All operations use Horreum's DataType methods (not direct Redis calls) target_instance.transaction do |_tx| # Add to collection using DataType method (ZADD/SADD/RPUSH) ParticipantMethods::Builder.add_to_collection( collection, self, score: score, type: type, target_class: target_instance.class, collection_name: collection_name, ) # Track participation for efficient cleanup using DataType method (SADD) track_participation_in(collection.dbkey) if respond_to?(:track_participation_in) end end end |
.build_membership_check(participant_class, target_name, collection_name, _type) ⇒ Object
Build method to check membership in target's collection Creates: domain.in_customer_domains?(customer)
57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/familia/features/relationships/participation/participant_methods.rb', line 57 def self.build_membership_check(participant_class, target_name, collection_name, _type) method_name = "in_#{target_name}_#{collection_name}?" participant_class.define_method(method_name) do |target_instance| return false unless target_instance&.identifier # Use Horreum's DataType accessor instead of manual creation collection = target_instance.send(collection_name) ParticipantMethods::Builder.member_of_collection?(collection, self) end end |
.build_position_method(participant_class, target_name, collection_name) ⇒ Object
Build position method for lists Creates: domain.position_in_customer_domains(customer)
144 145 146 147 148 149 150 151 152 153 154 155 |
# File 'lib/familia/features/relationships/participation/participant_methods.rb', line 144 def self.build_position_method(participant_class, target_name, collection_name) method_name = "position_in_#{target_name}_#{collection_name}" participant_class.define_method(method_name) do |target_instance| return nil unless target_instance&.identifier # Use Horreum's DataType accessor instead of manual key construction collection = target_instance.send(collection_name) # Use DataType method to find position (index in list) collection.to_a.index(identifier) end end |
.build_remove_from_target(participant_class, target_name, collection_name, type) ⇒ Object
Build method to remove self from target's collection Creates: domain.remove_from_customer_domains(customer)
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/familia/features/relationships/participation/participant_methods.rb', line 106 def self.build_remove_from_target(participant_class, target_name, collection_name, type) method_name = "remove_from_#{target_name}_#{collection_name}" participant_class.define_method(method_name) do |target_instance| return unless target_instance&.identifier # Use Horreum's DataType accessor instead of manual creation collection = target_instance.send(collection_name) # Use transaction for atomicity between collection remove and reverse index untracking # All operations use Horreum's DataType methods (not direct Redis calls) target_instance.transaction do |_tx| # Remove from collection using DataType method (ZREM/SREM/LREM) ParticipantMethods::Builder.remove_from_collection(collection, self, type: type) # Remove from participation tracking using DataType method (SREM) untrack_participation_in(collection.dbkey) if respond_to?(:untrack_participation_in) end end end |
.build_score_methods(participant_class, target_name, collection_name) ⇒ Object
Build score-related methods for sorted sets Creates: domain.score_in_customer_domains(customer) domain.update_score_in_customer_domains(customer, new_score)
130 131 132 133 134 135 136 137 138 139 140 |
# File 'lib/familia/features/relationships/participation/participant_methods.rb', line 130 def self.build_score_methods(participant_class, target_name, collection_name) # Get score method score_method = "score_in_#{target_name}_#{collection_name}" participant_class.define_method(score_method) do |target_instance| return nil unless target_instance&.identifier # Use Horreum's DataType accessor instead of manual key construction collection = target_instance.send(collection_name) collection.score(identifier) end end |