@@ -6,7 +6,7 @@ module JsonapiCompliable
6
6
# @attr_reader [Hash] sideloads The associated sibling sideloads
7
7
# @attr_reader [Proc] scope_proc The configured 'scope' block
8
8
# @attr_reader [Proc] assign_proc The configured 'assign' block
9
- # @attr_reader [Proc] grouper The configured 'group_by' proc
9
+ # @attr_reader [Symbol] grouping_field The configured 'group_by' symbol
10
10
# @attr_reader [Symbol] foreign_key The attribute used to match objects - need not be a true database foreign key.
11
11
# @attr_reader [Symbol] primary_key The attribute used to match objects - need not be a true database primary key.
12
12
# @attr_reader [Symbol] type One of :has_many, :belongs_to, etc
@@ -15,10 +15,11 @@ class Sideload
15
15
:resource_class ,
16
16
:polymorphic ,
17
17
:polymorphic_groups ,
18
+ :parent ,
18
19
:sideloads ,
19
20
:scope_proc ,
20
21
:assign_proc ,
21
- :grouper ,
22
+ :grouping_field ,
22
23
:foreign_key ,
23
24
:primary_key ,
24
25
:type
@@ -28,12 +29,13 @@ class Sideload
28
29
# An anonymous Resource will be assigned when none provided.
29
30
#
30
31
# @see Adapters::Abstract#sideloading_module
31
- def initialize ( name , type : nil , resource : nil , polymorphic : false , primary_key : :id , foreign_key : nil )
32
+ def initialize ( name , type : nil , resource : nil , polymorphic : false , primary_key : :id , foreign_key : nil , parent : nil )
32
33
@name = name
33
34
@resource_class = ( resource || Class . new ( Resource ) )
34
35
@sideloads = { }
35
36
@polymorphic = !!polymorphic
36
37
@polymorphic_groups = { } if polymorphic?
38
+ @parent = parent
37
39
@primary_key = primary_key
38
40
@foreign_key = foreign_key
39
41
@type = type
@@ -55,7 +57,7 @@ def resource
55
57
# +Business+ or +Government+:
56
58
#
57
59
# allow_sideload :organization, :polymorphic: true do
58
- # group_by { |record| record. organization_type }
60
+ # group_by : organization_type
59
61
#
60
62
# allow_sideload 'Business', resource: BusinessResource do
61
63
# # ... code ...
@@ -70,7 +72,7 @@ def resource
70
72
# with ActiveRecord:
71
73
#
72
74
# polymorphic_belongs_to :organization,
73
- # group_by: ->(office) { office. organization_type } ,
75
+ # group_by: : organization_type,
74
76
# groups: {
75
77
# 'Business' => {
76
78
# scope: -> { Business.all },
@@ -181,21 +183,25 @@ def assign(&blk)
181
183
# @see #name
182
184
# @see #type
183
185
def associate ( parent , child )
184
- resource_class . config [ :adapter ] . associate ( parent , child , name , type )
186
+ association_name = @parent ? @parent . name : name
187
+ resource_class . config [ :adapter ] . associate parent ,
188
+ child ,
189
+ association_name ,
190
+ type
185
191
end
186
192
187
- # Define a proc that groups the parent records. For instance, with
193
+ # Define an attribute that groups the parent records. For instance, with
188
194
# an ActiveRecord polymorphic belongs_to there will be a +parent_id+
189
195
# and +parent_type+. We would want to group on +parent_type+:
190
196
#
191
197
# allow_sideload :organization, polymorphic: true do
192
198
# # group parent_type, parent here is 'organization'
193
- # group_by ->(office) { office. organization_type }
199
+ # group_by : organization_type
194
200
# end
195
201
#
196
202
# @see #polymorphic?
197
- def group_by ( & grouper )
198
- @grouper = grouper
203
+ def group_by ( grouping_field )
204
+ @grouping_field = grouping_field
199
205
end
200
206
201
207
# Resolve the sideload.
@@ -323,6 +329,13 @@ def to_hash(processed = [])
323
329
result
324
330
end
325
331
332
+ # @api private
333
+ def polymorphic_child_for_type ( type )
334
+ polymorphic_groups . values . find do |v |
335
+ v . resource_class . config [ :type ] == type
336
+ end
337
+ end
338
+
326
339
private
327
340
328
341
def nested_sideload_hash ( sideload , processed )
@@ -333,8 +346,24 @@ def nested_sideload_hash(sideload, processed)
333
346
end
334
347
end
335
348
349
+ def polymorphic_grouper ( grouping_field )
350
+ lambda do |record |
351
+ if record . is_a? ( Hash )
352
+ if record . keys [ 0 ] . is_a? ( Symbol )
353
+ record [ grouping_field ]
354
+ else
355
+ record [ grouping_field . to_s ]
356
+ end
357
+ else
358
+ record . send ( grouping_field )
359
+ end
360
+ end
361
+ end
362
+
336
363
def resolve_polymorphic ( parents , query )
337
- parents . group_by ( &@grouper ) . each_pair do |group_type , group_members |
364
+ grouper = polymorphic_grouper ( @grouping_field )
365
+
366
+ parents . group_by ( &grouper ) . each_pair do |group_type , group_members |
338
367
sideload_for_group = @polymorphic_groups [ group_type ]
339
368
if sideload_for_group
340
369
sideload_for_group . resolve ( group_members , query , name )
0 commit comments