@@ -90,7 +90,7 @@ def self.prepended(base)
90
90
class << base
91
91
delegate :jit_preload , to : :all
92
92
93
- def has_many_aggregate ( assoc , name , aggregate , field , table_alias_name : nil , default : 0 )
93
+ def has_many_aggregate ( assoc , name , aggregate , field , table_alias_name : nil , default : 0 , max_ids_per_query : nil )
94
94
method_name = "#{ assoc } _#{ name } "
95
95
96
96
define_method ( method_name ) do |conditions = { } |
@@ -101,6 +101,13 @@ def has_many_aggregate(assoc, name, aggregate, field, table_alias_name: nil, def
101
101
if jit_preloader
102
102
reflection = association ( assoc ) . reflection
103
103
primary_ids = jit_preloader . records . collect { |r | r [ reflection . active_record_primary_key ] }
104
+ max_ids_per_query = max_ids_per_query || JitPreloader . max_ids_per_query
105
+ if max_ids_per_query
106
+ slices = primary_ids . each_slice ( max_ids_per_query )
107
+ else
108
+ slices = [ primary_ids ]
109
+ end
110
+
104
111
klass = reflection . klass
105
112
106
113
aggregate_association = reflection
@@ -115,27 +122,29 @@ def has_many_aggregate(assoc, name, aggregate, field, table_alias_name: nil, def
115
122
table_reference = table_alias_name
116
123
table_reference ||= association_scope . references_values . first || aggregate_association . table_name
117
124
118
- conditions [ table_reference ] = { aggregate_association . foreign_key => primary_ids }
119
-
120
125
# If the association is a STI child model, specify its type in the condition so that it
121
126
# doesn't include results from other child models
122
127
parent_is_base_class = aggregate_association . klass . superclass . abstract_class? || aggregate_association . klass . superclass == ActiveRecord ::Base
123
128
has_type_column = aggregate_association . klass . column_names . include? ( aggregate_association . klass . inheritance_column )
124
129
is_child_sti_model = !parent_is_base_class && has_type_column
125
130
if is_child_sti_model
126
- conditions [ table_reference ] . merge! ( { aggregate_association . klass . inheritance_column => aggregate_association . klass . sti_name } )
131
+ conditions [ table_reference ] = { aggregate_association . klass . inheritance_column => aggregate_association . klass . sti_name }
127
132
end
128
133
129
134
if reflection . type . present?
130
135
conditions [ reflection . type ] = self . class . name
131
136
end
132
137
group_by = "#{ table_reference } .#{ aggregate_association . foreign_key } "
133
138
134
- preloaded_data = Hash [ association_scope
135
- . where ( conditions )
136
- . group ( group_by )
137
- . send ( aggregate , field )
138
- ]
139
+ preloaded_data = { }
140
+ slices . each do |slice |
141
+ data = Hash [ association_scope
142
+ . where ( conditions . deep_merge ( table_reference => { aggregate_association . foreign_key => slice } ) )
143
+ . group ( group_by )
144
+ . send ( aggregate , field )
145
+ ]
146
+ preloaded_data . merge! ( data )
147
+ end
139
148
140
149
jit_preloader . records . each do |record |
141
150
record . jit_preload_aggregates ||= { }
0 commit comments