summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouwe Maan <douwe@gitlab.com>2015-10-14 09:17:05 +0200
committerDouwe Maan <douwe@gitlab.com>2015-10-14 09:17:05 +0200
commitd6fb96b9276d1a9edfae261d2eba2f79f8a9f340 (patch)
tree848a0fe95e83d125eaa1ab49b497a2626fb6284c
parentcd2583a3beed95a91eddf4e6f868507dcf499481 (diff)
downloadgitlab-ce-d6fb96b9276d1a9edfae261d2eba2f79f8a9f340.tar.gz
Have Issue#participants load all users mentioned in notes using a single query
-rw-r--r--app/models/concerns/mentionable.rb8
-rw-r--r--app/models/concerns/participable.rb23
-rw-r--r--lib/gitlab/reference_extractor.rb21
3 files changed, 28 insertions, 24 deletions
diff --git a/app/models/concerns/mentionable.rb b/app/models/concerns/mentionable.rb
index 7ad8d5b7da7..9339ecc4bce 100644
--- a/app/models/concerns/mentionable.rb
+++ b/app/models/concerns/mentionable.rb
@@ -47,19 +47,19 @@ module Mentionable
SystemNoteService.cross_reference_exists?(target, local_reference)
end
- def mentioned_users(current_user = nil)
+ def mentioned_users(current_user = nil, load_lazy_references: true)
return [] if mentionable_text.blank?
- ext = Gitlab::ReferenceExtractor.new(self.project, current_user)
+ ext = Gitlab::ReferenceExtractor.new(self.project, current_user, load_lazy_references: load_lazy_references)
ext.analyze(mentionable_text)
ext.users.uniq
end
# Extract GFM references to other Mentionables from this Mentionable. Always excludes its #local_reference.
- def references(p = project, current_user = self.author, text = mentionable_text)
+ def references(p = project, current_user = self.author, text = mentionable_text, load_lazy_references: true)
return [] if text.blank?
- ext = Gitlab::ReferenceExtractor.new(p, current_user)
+ ext = Gitlab::ReferenceExtractor.new(p, current_user, load_lazy_references: load_lazy_references)
ext.analyze(text)
(ext.issues + ext.merge_requests + ext.commits).uniq - [local_reference]
end
diff --git a/app/models/concerns/participable.rb b/app/models/concerns/participable.rb
index 7c9597333dd..7a2bea567df 100644
--- a/app/models/concerns/participable.rb
+++ b/app/models/concerns/participable.rb
@@ -27,7 +27,7 @@ module Participable
module ClassMethods
def participant(*attrs)
- participant_attrs.concat(attrs.map(&:to_s))
+ participant_attrs.concat(attrs)
end
def participant_attrs
@@ -37,13 +37,12 @@ module Participable
# Be aware that this method makes a lot of sql queries.
# Save result into variable if you are going to reuse it inside same request
- def participants(current_user = self.author, project = self.project)
+ def participants(current_user = self.author, project = self.project, load_lazy_references: true)
participants = self.class.participant_attrs.flat_map do |attr|
meth = method(attr)
-
value =
- if meth.arity == 1 || meth.arity == -1
- meth.call(current_user)
+ if attr == :mentioned_users
+ meth.call(current_user, load_lazy_references: false)
else
meth.call
end
@@ -51,9 +50,13 @@ module Participable
participants_for(value, current_user, project)
end.compact.uniq
- if project
- participants.select! do |user|
- user.can?(:read_project, project)
+ if load_lazy_references
+ participants = Gitlab::Markdown::ReferenceFilter::LazyReference.load(participants).uniq
+
+ if project
+ participants.select! do |user|
+ user.can?(:read_project, project)
+ end
end
end
@@ -64,12 +67,12 @@ module Participable
def participants_for(value, current_user = nil, project = nil)
case value
- when User
+ when User, Gitlab::Markdown::ReferenceFilter::LazyReference
[value]
when Enumerable, ActiveRecord::Relation
value.flat_map { |v| participants_for(v, current_user, project) }
when Participable
- value.participants(current_user, project)
+ value.participants(current_user, project, load_lazy_references: false)
end
end
end
diff --git a/lib/gitlab/reference_extractor.rb b/lib/gitlab/reference_extractor.rb
index d6b739d7b9a..895a23ddcc8 100644
--- a/lib/gitlab/reference_extractor.rb
+++ b/lib/gitlab/reference_extractor.rb
@@ -3,17 +3,17 @@ require 'gitlab/markdown'
module Gitlab
# Extract possible GFM references from an arbitrary String for further processing.
class ReferenceExtractor
- attr_accessor :project, :current_user
+ attr_accessor :project, :current_user, :load_lazy_references
- def initialize(project, current_user = nil)
+ def initialize(project, current_user = nil, load_lazy_references: true)
@project = project
@current_user = current_user
+ @load_lazy_references = load_lazy_references
end
- def analyze(texts)
+ def analyze(text)
references.clear
- texts = Array(texts)
- @texts = texts.map { |text| Gitlab::Markdown.render_without_gfm(text) }
+ @text = Gitlab::Markdown.render_without_gfm(text)
end
%i(user label issue merge_request snippet commit commit_range).each do |type|
@@ -29,7 +29,7 @@ module Gitlab
type = type.to_sym
return references[type] if references.has_key?(type)
- references[type] = pipeline_result(type).uniq
+ references[type] = pipeline_result(type)
end
end
@@ -53,14 +53,15 @@ module Gitlab
}
pipeline = HTML::Pipeline.new([filter, Gitlab::Markdown::ReferenceGathererFilter], context)
+ result = pipeline.call(@text)
- values = @texts.flat_map do |text|
- result = pipeline.call(text)
+ values = result[:references][filter_type].uniq
- result[:references][filter_type]
+ if @load_lazy_references
+ values = Gitlab::Markdown::ReferenceFilter::LazyReference.load(values).uniq
end
- Gitlab::Markdown::ReferenceFilter::LazyReference.load(values)
+ values
end
end
end