diff options
author | Markus Koller <mkoller@gitlab.com> | 2019-09-02 14:12:20 +0300 |
---|---|---|
committer | Markus Koller <mkoller@gitlab.com> | 2019-09-10 16:24:28 +0300 |
commit | 60755fbc406bd25ab526339899f97a2b27aeb272 (patch) | |
tree | a60f6fa9beb0c4ccdc27c5f7734c14bc34ad2d21 /lib/gitlab/noteable_metadata.rb | |
parent | 08b0613302ec813c0735e2c0447a3f7683d7ab87 (diff) |
Optimize queries for snippet listings
- Avoid N+1 queries for authors and comment counts
- Avoid an additional snippet existence query
Diffstat (limited to 'lib/gitlab/noteable_metadata.rb')
-rw-r--r-- | lib/gitlab/noteable_metadata.rb | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/lib/gitlab/noteable_metadata.rb b/lib/gitlab/noteable_metadata.rb new file mode 100644 index 00000000000..f3f8933b81f --- /dev/null +++ b/lib/gitlab/noteable_metadata.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +module Gitlab + module NoteableMetadata + def noteable_meta_data(noteable_collection, collection_type) + # ActiveRecord uses Object#extend for null relations. + if !(noteable_collection.singleton_class < ActiveRecord::NullRelation) && + noteable_collection.respond_to?(:limit_value) && + noteable_collection.limit_value.nil? + + raise 'Collection must have a limit applied for preloading meta-data' + end + + # map has to be used here since using pluck or select will + # throw an error when ordering noteables which inserts + # a new order into the collection. + # We cannot use reorder to not mess up the paginated collection. + noteable_ids = noteable_collection.map(&:id) + + return {} if noteable_ids.empty? + + noteable_notes_count = ::Note.count_for_collection(noteable_ids, collection_type) + + noteable_ids.each_with_object({}) do |id, noteable_meta| + notes = noteable_notes_count.find { |notes| notes.noteable_id == id } + + noteable_meta[id] = ::Noteable::NoteableMeta.new( + notes.try(:count).to_i + ) + end + end + end +end |