@@ -157,7 +157,7 @@ module ::DiscourseAssign
157157 Site . preloaded_category_custom_fields << "enable_unassigned_filter"
158158 end
159159
160- BookmarkQuery . on_preload do |bookmarks , bookmark_query |
160+ BookmarkQuery . on_preload do |bookmarks , _bookmark_query |
161161 if SiteSetting . assign_enabled?
162162 topics =
163163 Bookmark
@@ -173,8 +173,10 @@ module ::DiscourseAssign
173173 . index_by ( &:topic_id )
174174
175175 topics . each do |topic |
176- assigned_to = assignments [ topic . id ] &.assigned_to
177- topic . preload_assigned_to ( assigned_to )
176+ assignment = assignments [ topic . id ]
177+ # NOTE: preloading to `nil` is necessary to avoid N+1 queries
178+ topic . preload_assigned_to ( assignment &.assigned_to )
179+ topic . preload_assignment_status ( assignment &.status )
178180 end
179181 end
180182 end
@@ -184,101 +186,102 @@ module ::DiscourseAssign
184186 end
185187
186188 TopicList . on_preload do |topics , topic_list |
187- if SiteSetting . assign_enabled?
188- can_assign = topic_list . current_user && topic_list . current_user . can_assign?
189- allowed_access = SiteSetting . assigns_public || can_assign
190-
191- if allowed_access && topics . length > 0
192- assignments =
193- Assignment . strict_loading . active . where ( topic : topics ) . includes ( :target , :assigned_to )
194- assignments_map = assignments . group_by ( &:topic_id )
195-
196- user_ids =
197- assignments . filter { |assignment | assignment . assigned_to_user? } . map ( &:assigned_to_id )
198- users_map = User . where ( id : user_ids ) . select ( UserLookup . lookup_columns ) . index_by ( &:id )
199-
200- group_ids =
201- assignments . filter { |assignment | assignment . assigned_to_group? } . map ( &:assigned_to_id )
202- groups_map = Group . where ( id : group_ids ) . index_by ( &:id )
203-
204- topics . each do |topic |
205- assignments = assignments_map [ topic . id ]
206- direct_assignment =
207- assignments &.find do |assignment |
208- assignment . target_type == "Topic" && assignment . target_id == topic . id
209- end
210- indirectly_assigned_to = { }
211- assignments
212- &.each do |assignment |
213- next if assignment . target_type == "Topic"
214- next if !assignment . target
215- next (
216- indirectly_assigned_to [ assignment . target_id ] = {
217- assigned_to : users_map [ assignment . assigned_to_id ] ,
218- post_number : assignment . target . post_number ,
219- }
220- ) if assignment &.assigned_to_user?
221- next (
222- indirectly_assigned_to [ assignment . target_id ] = {
223- assigned_to : groups_map [ assignment . assigned_to_id ] ,
224- post_number : assignment . target . post_number ,
225- }
226- ) if assignment &.assigned_to_group?
227- end
228- &.compact
229- &.uniq
230-
231- assigned_to =
232- if direct_assignment &.assigned_to_user?
233- users_map [ direct_assignment . assigned_to_id ]
234- elsif direct_assignment &.assigned_to_group?
235- groups_map [ direct_assignment . assigned_to_id ]
236- end
237- topic . preload_assigned_to ( assigned_to )
238- topic . preload_indirectly_assigned_to ( indirectly_assigned_to )
189+ next unless SiteSetting . assign_enabled?
190+
191+ can_assign = topic_list . current_user &.can_assign?
192+ allowed_access = SiteSetting . assigns_public || can_assign
193+
194+ next if !allowed_access || topics . empty?
195+
196+ assignments =
197+ Assignment . strict_loading . active . where ( topic : topics ) . includes ( :target , :assigned_to )
198+ assignments_map = assignments . group_by ( &:topic_id )
199+
200+ user_ids = assignments . filter ( &:assigned_to_user? ) . map ( &:assigned_to_id )
201+ users_map = User . where ( id : user_ids ) . select ( UserLookup . lookup_columns ) . index_by ( &:id )
202+
203+ group_ids = assignments . filter ( &:assigned_to_group? ) . map ( &:assigned_to_id )
204+ groups_map = Group . where ( id : group_ids ) . index_by ( &:id )
205+
206+ topics . each do |topic |
207+ if assignments = assignments_map [ topic . id ]
208+ topic_assignments , post_assignments = assignments . partition { _1 . target_type == "Topic" }
209+
210+ direct_assignment = topic_assignments . find { _1 . target_id == topic . id }
211+
212+ indirectly_assigned_to = { }
213+
214+ post_assignments . each do |assignment |
215+ next unless assignment . target
216+
217+ if assignment . assigned_to_user?
218+ indirectly_assigned_to [ assignment . target_id ] = {
219+ assigned_to : users_map [ assignment . assigned_to_id ] ,
220+ post_number : assignment . target . post_number ,
221+ }
222+ elsif assignment . assigned_to_group?
223+ indirectly_assigned_to [ assignment . target_id ] = {
224+ assigned_to : groups_map [ assignment . assigned_to_id ] ,
225+ post_number : assignment . target . post_number ,
226+ }
227+ end
239228 end
229+
230+ assigned_to =
231+ if direct_assignment &.assigned_to_user?
232+ users_map [ direct_assignment . assigned_to_id ]
233+ elsif direct_assignment &.assigned_to_group?
234+ groups_map [ direct_assignment . assigned_to_id ]
235+ end
240236 end
237+
238+ # NOTE: preloading to `nil` is necessary to avoid N+1 queries
239+ topic . preload_assigned_to ( assigned_to )
240+ topic . preload_assignment_status ( direct_assignment &.status )
241+ topic . preload_indirectly_assigned_to ( indirectly_assigned_to )
241242 end
242243 end
243244
244245 Search . on_preload do |results , search |
245- if SiteSetting . assign_enabled?
246- can_assign = search . guardian &.can_assign?
247- allowed_access = SiteSetting . assigns_public || can_assign
248-
249- if allowed_access && results . posts . length > 0
250- topics = results . posts . map ( &:topic )
251- assignments =
252- Assignment
253- . strict_loading
254- . where ( topic : topics , active : true )
255- . includes ( :assigned_to , :target )
256- . group_by ( &:topic_id )
257-
258- results . posts . each do |post |
259- topic_assignments = assignments [ post . topic . id ]
260- direct_assignment =
261- topic_assignments &.find { |assignment | assignment . target_type == "Topic" }
262- indirect_assignments =
263- topic_assignments &.select { |assignment | assignment . target_type == "Post" }
264-
265- post . topic . preload_assigned_to ( direct_assignment &.assigned_to )
266- post . topic . preload_indirectly_assigned_to ( nil )
267- if indirect_assignments . present?
268- indirect_assignment_map =
269- indirect_assignments . reduce ( { } ) do |acc , assignment |
270- if assignment . target
271- acc [ assignment . target_id ] = {
272- assigned_to : assignment . assigned_to ,
273- post_number : assignment . target . post_number ,
274- }
275- end
276- acc
277- end
278- post . topic . preload_indirectly_assigned_to ( indirect_assignment_map )
279- end
246+ next unless SiteSetting . assign_enabled?
247+
248+ can_assign = search . guardian &.can_assign?
249+ allowed_access = SiteSetting . assigns_public || can_assign
250+
251+ next if !allowed_access || results . posts . empty?
252+
253+ topics = results . posts . map ( &:topic )
254+
255+ assignments =
256+ Assignment
257+ . strict_loading
258+ . active
259+ . where ( topic : topics )
260+ . includes ( :assigned_to , :target )
261+ . group_by ( &:topic_id )
262+
263+ results . posts . each do |post |
264+ if topic_assignments = assignments [ post . topic_id ]
265+ direct_assignment = topic_assignments . find { _1 . target_type == "Topic" }
266+ indirect_assignments = topic_assignments . select { _1 . target_type == "Post" }
267+ end
268+
269+ if indirect_assignments . present?
270+ indirect_assignment_map = { }
271+
272+ indirect_assignments . each do |assignment |
273+ next unless assignment . target
274+ indirect_assignment_map [ assignment . target_id ] = {
275+ assigned_to : assignment . assigned_to ,
276+ post_number : assignment . target . post_number ,
277+ }
280278 end
281279 end
280+
281+ # NOTE: preloading to `nil` is necessary to avoid N+1 queries
282+ post . topic . preload_assigned_to ( direct_assignment &.assigned_to )
283+ post . topic . preload_assignment_status ( direct_assignment &.status )
284+ post . topic . preload_indirectly_assigned_to ( indirect_assignment_map )
282285 end
283286 end
284287
@@ -442,6 +445,11 @@ module ::DiscourseAssign
442445 @assigned_to = assignment . assigned_to if assignment &.active
443446 end
444447
448+ add_to_class ( :topic , :assignment_status ) do
449+ return @assignment_status if defined? ( @assignment_status )
450+ @assignment_status = assignment . status if SiteSetting . enable_assign_status && assignment &.active
451+ end
452+
445453 add_to_class ( :topic , :indirectly_assigned_to ) do
446454 return @indirectly_assigned_to if defined? ( @indirectly_assigned_to )
447455 @indirectly_assigned_to =
@@ -465,6 +473,10 @@ module ::DiscourseAssign
465473
466474 add_to_class ( :topic , :preload_assigned_to ) { |assigned_to | @assigned_to = assigned_to }
467475
476+ add_to_class ( :topic , :preload_assignment_status ) do |assignment_status |
477+ @assignment_status = assignment_status
478+ end
479+
468480 add_to_class ( :topic , :preload_indirectly_assigned_to ) do |indirectly_assigned_to |
469481 @indirectly_assigned_to = indirectly_assigned_to
470482 end
@@ -531,9 +543,9 @@ module ::DiscourseAssign
531543 :assignment_status ,
532544 include_condition : -> do
533545 SiteSetting . enable_assign_status && ( SiteSetting . assigns_public || scope . can_assign? ) &&
534- object . topic . assignment . present?
546+ object . topic . assignment_status . present?
535547 end ,
536- ) { object . topic . assignment . status }
548+ ) { object . topic . assignment_status }
537549
538550 # SuggestedTopic serializer
539551 add_to_serializer (
@@ -590,9 +602,9 @@ module ::DiscourseAssign
590602 :assignment_status ,
591603 include_condition : -> do
592604 SiteSetting . enable_assign_status && ( SiteSetting . assigns_public || scope . can_assign? ) &&
593- object . assignment . present?
605+ object . assignment_status . present?
594606 end ,
595- ) { object . assignment . status }
607+ ) { object . assignment_status }
596608
597609 # SearchTopicListItem serializer
598610 add_to_serializer (
0 commit comments