familia 2.0.0.pre22 → 2.0.0.pre23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/claude-code-review.yml +8 -5
- data/CHANGELOG.rst +33 -0
- data/Gemfile.lock +8 -8
- data/docs/1106-participates_in-bidirectional-solution.md +201 -58
- data/examples/through_relationships.rb +275 -0
- data/lib/familia/features/relationships/README.md +1 -1
- data/lib/familia/features/relationships/participation/participant_methods.rb +59 -10
- data/lib/familia/features/relationships/participation/target_methods.rb +51 -7
- data/lib/familia/features/relationships/participation/through_model_operations.rb +150 -0
- data/lib/familia/features/relationships/participation.rb +39 -15
- data/lib/familia/features/relationships/participation_relationship.rb +19 -1
- data/lib/familia/features/relationships.rb +1 -1
- data/lib/familia/version.rb +1 -1
- data/pr_agent.toml +6 -1
- data/try/features/relationships/participation_commands_verification_spec.rb +1 -1
- data/try/features/relationships/participation_commands_verification_try.rb +1 -1
- data/try/features/relationships/participation_method_prefix_try.rb +133 -0
- data/try/features/relationships/participation_reverse_index_try.rb +1 -1
- data/try/features/relationships/{participation_bidirectional_try.rb → participation_reverse_methods_try.rb} +6 -6
- data/try/features/relationships/participation_through_try.rb +173 -0
- metadata +6 -2
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
# try/features/relationships/participation_through_try.rb
|
|
2
|
+
#
|
|
3
|
+
# frozen_string_literal: true
|
|
4
|
+
|
|
5
|
+
# Test through model support for participates_in relationships
|
|
6
|
+
|
|
7
|
+
require_relative '../../support/helpers/test_helpers'
|
|
8
|
+
|
|
9
|
+
# Define through model FIRST so it can be resolved
|
|
10
|
+
class ::ThroughTestMembership < Familia::Horreum
|
|
11
|
+
feature :object_identifier
|
|
12
|
+
feature :relationships
|
|
13
|
+
identifier_field :objid
|
|
14
|
+
field :through_test_customer_objid
|
|
15
|
+
field :through_test_domain_objid
|
|
16
|
+
field :role
|
|
17
|
+
field :updated_at
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
class ::ThroughTestCustomer < Familia::Horreum
|
|
21
|
+
feature :object_identifier
|
|
22
|
+
feature :relationships
|
|
23
|
+
identifier_field :custid
|
|
24
|
+
field :custid
|
|
25
|
+
field :name
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
class ::ThroughTestDomain < Familia::Horreum
|
|
29
|
+
feature :object_identifier
|
|
30
|
+
feature :relationships
|
|
31
|
+
identifier_field :domain_id
|
|
32
|
+
field :domain_id
|
|
33
|
+
field :display_domain
|
|
34
|
+
field :created_at
|
|
35
|
+
participates_in ThroughTestCustomer, :domains, score: :created_at, through: :ThroughTestMembership
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Define backward compat classes in setup
|
|
39
|
+
class ::BackwardCompatCustomer < Familia::Horreum
|
|
40
|
+
feature :relationships
|
|
41
|
+
identifier_field :custid
|
|
42
|
+
field :custid
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
class ::BackwardCompatDomain < Familia::Horreum
|
|
46
|
+
feature :relationships
|
|
47
|
+
identifier_field :domain_id
|
|
48
|
+
field :domain_id
|
|
49
|
+
field :created_at
|
|
50
|
+
participates_in BackwardCompatCustomer, :domains, score: :created_at
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Setup instance variables
|
|
54
|
+
@customer = ThroughTestCustomer.new(custid: 'cust_through_123', name: 'Through Test Customer')
|
|
55
|
+
@domain = ThroughTestDomain.new(domain_id: 'dom_through_456', display_domain: 'through-test.com', created_at: Familia.now.to_i)
|
|
56
|
+
@customer.save
|
|
57
|
+
@domain.save
|
|
58
|
+
|
|
59
|
+
@compat_customer = BackwardCompatCustomer.new(custid: 'compat_cust')
|
|
60
|
+
@compat_domain = BackwardCompatDomain.new(domain_id: 'compat_dom', created_at: Familia.now.to_i)
|
|
61
|
+
@compat_customer.save
|
|
62
|
+
@compat_domain.save
|
|
63
|
+
|
|
64
|
+
## ParticipationRelationship supports through parameter
|
|
65
|
+
Familia::Features::Relationships::ParticipationRelationship.members.include?(:through)
|
|
66
|
+
#=> true
|
|
67
|
+
|
|
68
|
+
## participates_in creates relationship with through parameter
|
|
69
|
+
@rel = ThroughTestDomain.participation_relationships.first
|
|
70
|
+
@rel.through
|
|
71
|
+
#=> :ThroughTestMembership
|
|
72
|
+
|
|
73
|
+
## Through class must have object_identifier feature
|
|
74
|
+
begin
|
|
75
|
+
class ::InvalidThroughModel < Familia::Horreum
|
|
76
|
+
feature :relationships
|
|
77
|
+
end
|
|
78
|
+
class ::BadDomain < Familia::Horreum
|
|
79
|
+
feature :relationships
|
|
80
|
+
field :name
|
|
81
|
+
participates_in ThroughTestCustomer, :bad_domains, through: :InvalidThroughModel
|
|
82
|
+
end
|
|
83
|
+
false
|
|
84
|
+
rescue ArgumentError => e
|
|
85
|
+
e.message.include?('must use `feature :object_identifier`')
|
|
86
|
+
end
|
|
87
|
+
#=> true
|
|
88
|
+
|
|
89
|
+
## Adding domain creates through model automatically
|
|
90
|
+
@membership1 = @customer.add_domains_instance(@domain)
|
|
91
|
+
@through_key = "through_test_customer:#{@customer.objid}:through_test_domain:#{@domain.objid}:through_test_membership"
|
|
92
|
+
@loaded_membership = ThroughTestMembership.load(@through_key)
|
|
93
|
+
@loaded_membership&.exists?
|
|
94
|
+
#=> true
|
|
95
|
+
|
|
96
|
+
## Through model receives through_attrs on add
|
|
97
|
+
@customer.remove_domains_instance(@domain)
|
|
98
|
+
@membership2 = @customer.add_domains_instance(@domain, through_attrs: { role: 'admin' })
|
|
99
|
+
@loaded_with_role = ThroughTestMembership.load(@through_key)
|
|
100
|
+
@loaded_with_role.role
|
|
101
|
+
#=> 'admin'
|
|
102
|
+
|
|
103
|
+
## add_domains_instance returns through model when using :through
|
|
104
|
+
@membership2.class.name
|
|
105
|
+
#=> "ThroughTestMembership"
|
|
106
|
+
|
|
107
|
+
## Returned through model can be chained
|
|
108
|
+
@membership2.respond_to?(:role)
|
|
109
|
+
#=> true
|
|
110
|
+
|
|
111
|
+
## Returned through model has role attribute set
|
|
112
|
+
@membership2.role
|
|
113
|
+
#=> 'admin'
|
|
114
|
+
|
|
115
|
+
## Removing domain destroys through model
|
|
116
|
+
@customer.remove_domains_instance(@domain)
|
|
117
|
+
@removed_check = ThroughTestMembership.load(@through_key)
|
|
118
|
+
@removed_check.nil? || !@removed_check.exists?
|
|
119
|
+
#=> true
|
|
120
|
+
|
|
121
|
+
## Adding twice updates existing, doesn't duplicate
|
|
122
|
+
@membership_v1 = @customer.add_domains_instance(@domain, through_attrs: { role: 'viewer' })
|
|
123
|
+
@check_v1 = ThroughTestMembership.load(@through_key)
|
|
124
|
+
@check_v1.role
|
|
125
|
+
#=> 'viewer'
|
|
126
|
+
|
|
127
|
+
## Second add updates the same through model
|
|
128
|
+
@membership_v2 = @customer.add_domains_instance(@domain, through_attrs: { role: 'editor' })
|
|
129
|
+
@check_v2 = ThroughTestMembership.load(@through_key)
|
|
130
|
+
@check_v2.role
|
|
131
|
+
#=> 'editor'
|
|
132
|
+
|
|
133
|
+
## Only one through model exists (same objid)
|
|
134
|
+
@check_v1.objid == @check_v2.objid
|
|
135
|
+
#=> true
|
|
136
|
+
|
|
137
|
+
## Models without :through work as before
|
|
138
|
+
@compat_result = @compat_customer.add_domains_instance(@compat_domain)
|
|
139
|
+
@compat_domain.in_backward_compat_customer_domains?(@compat_customer)
|
|
140
|
+
#=> true
|
|
141
|
+
|
|
142
|
+
## No through model created for backward compat
|
|
143
|
+
@compat_rel = BackwardCompatDomain.participation_relationships.first
|
|
144
|
+
@compat_rel.through.nil?
|
|
145
|
+
#=> true
|
|
146
|
+
|
|
147
|
+
## Backward compat returns self not through model
|
|
148
|
+
@compat_result.class.name
|
|
149
|
+
#=> "BackwardCompatCustomer"
|
|
150
|
+
|
|
151
|
+
## Through model sets updated_at on create
|
|
152
|
+
@customer.remove_domains_instance(@domain)
|
|
153
|
+
@membership_with_ts = @customer.add_domains_instance(@domain, through_attrs: { role: 'owner' })
|
|
154
|
+
@ts_check = ThroughTestMembership.load(@through_key)
|
|
155
|
+
@ts_check.updated_at.is_a?(Float)
|
|
156
|
+
#=> true
|
|
157
|
+
|
|
158
|
+
## updated_at is current
|
|
159
|
+
(Familia.now.to_f - @ts_check.updated_at) < 2.0
|
|
160
|
+
#=> true
|
|
161
|
+
|
|
162
|
+
## Through model updates updated_at on attribute change
|
|
163
|
+
@old_ts = @ts_check.updated_at
|
|
164
|
+
sleep 0.1
|
|
165
|
+
@membership_updated = @customer.add_domains_instance(@domain, through_attrs: { role: 'admin' })
|
|
166
|
+
@new_ts_check = ThroughTestMembership.load(@through_key)
|
|
167
|
+
@new_ts_check.updated_at > @old_ts
|
|
168
|
+
#=> true
|
|
169
|
+
|
|
170
|
+
# Cleanup
|
|
171
|
+
[@customer, @domain, @compat_customer, @compat_domain].each do |obj|
|
|
172
|
+
obj.destroy! if obj&.respond_to?(:destroy!) && obj.exists?
|
|
173
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: familia
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.0.0.
|
|
4
|
+
version: 2.0.0.pre23
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Delano Mandelbaum
|
|
@@ -218,6 +218,7 @@ files:
|
|
|
218
218
|
- examples/safe_dump.rb
|
|
219
219
|
- examples/sampling_demo.rb
|
|
220
220
|
- examples/single_connection_transaction_confusions.rb
|
|
221
|
+
- examples/through_relationships.rb
|
|
221
222
|
- familia.gemspec
|
|
222
223
|
- lib/familia.rb
|
|
223
224
|
- lib/familia/base.rb
|
|
@@ -275,6 +276,7 @@ files:
|
|
|
275
276
|
- lib/familia/features/relationships/participation/participant_methods.rb
|
|
276
277
|
- lib/familia/features/relationships/participation/rebuild_strategies.md
|
|
277
278
|
- lib/familia/features/relationships/participation/target_methods.rb
|
|
279
|
+
- lib/familia/features/relationships/participation/through_model_operations.rb
|
|
278
280
|
- lib/familia/features/relationships/participation_membership.rb
|
|
279
281
|
- lib/familia/features/relationships/participation_relationship.rb
|
|
280
282
|
- lib/familia/features/relationships/score_encoding.rb
|
|
@@ -361,12 +363,14 @@ files:
|
|
|
361
363
|
- try/features/relationships/indexing_commands_verification_try.rb
|
|
362
364
|
- try/features/relationships/indexing_rebuild_try.rb
|
|
363
365
|
- try/features/relationships/indexing_try.rb
|
|
364
|
-
- try/features/relationships/participation_bidirectional_try.rb
|
|
365
366
|
- try/features/relationships/participation_commands_verification_spec.rb
|
|
366
367
|
- try/features/relationships/participation_commands_verification_try.rb
|
|
368
|
+
- try/features/relationships/participation_method_prefix_try.rb
|
|
367
369
|
- try/features/relationships/participation_performance_improvements_try.rb
|
|
368
370
|
- try/features/relationships/participation_reverse_index_try.rb
|
|
371
|
+
- try/features/relationships/participation_reverse_methods_try.rb
|
|
369
372
|
- try/features/relationships/participation_target_class_resolution_try.rb
|
|
373
|
+
- try/features/relationships/participation_through_try.rb
|
|
370
374
|
- try/features/relationships/participation_unresolved_target_try.rb
|
|
371
375
|
- try/features/relationships/relationships_api_changes_try.rb
|
|
372
376
|
- try/features/relationships/relationships_edge_cases_try.rb
|