Have Issue#participants load all users mentioned in notes using a single query
This commit is contained in:
parent
cd2583a3be
commit
d6fb96b927
|
@ -47,19 +47,19 @@ module Mentionable
|
||||||
SystemNoteService.cross_reference_exists?(target, local_reference)
|
SystemNoteService.cross_reference_exists?(target, local_reference)
|
||||||
end
|
end
|
||||||
|
|
||||||
def mentioned_users(current_user = nil)
|
def mentioned_users(current_user = nil, load_lazy_references: true)
|
||||||
return [] if mentionable_text.blank?
|
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.analyze(mentionable_text)
|
||||||
ext.users.uniq
|
ext.users.uniq
|
||||||
end
|
end
|
||||||
|
|
||||||
# Extract GFM references to other Mentionables from this Mentionable. Always excludes its #local_reference.
|
# 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?
|
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.analyze(text)
|
||||||
(ext.issues + ext.merge_requests + ext.commits).uniq - [local_reference]
|
(ext.issues + ext.merge_requests + ext.commits).uniq - [local_reference]
|
||||||
end
|
end
|
||||||
|
|
|
@ -27,7 +27,7 @@ module Participable
|
||||||
|
|
||||||
module ClassMethods
|
module ClassMethods
|
||||||
def participant(*attrs)
|
def participant(*attrs)
|
||||||
participant_attrs.concat(attrs.map(&:to_s))
|
participant_attrs.concat(attrs)
|
||||||
end
|
end
|
||||||
|
|
||||||
def participant_attrs
|
def participant_attrs
|
||||||
|
@ -37,13 +37,12 @@ module Participable
|
||||||
|
|
||||||
# Be aware that this method makes a lot of sql queries.
|
# 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
|
# 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|
|
participants = self.class.participant_attrs.flat_map do |attr|
|
||||||
meth = method(attr)
|
meth = method(attr)
|
||||||
|
|
||||||
value =
|
value =
|
||||||
if meth.arity == 1 || meth.arity == -1
|
if attr == :mentioned_users
|
||||||
meth.call(current_user)
|
meth.call(current_user, load_lazy_references: false)
|
||||||
else
|
else
|
||||||
meth.call
|
meth.call
|
||||||
end
|
end
|
||||||
|
@ -51,11 +50,15 @@ module Participable
|
||||||
participants_for(value, current_user, project)
|
participants_for(value, current_user, project)
|
||||||
end.compact.uniq
|
end.compact.uniq
|
||||||
|
|
||||||
|
if load_lazy_references
|
||||||
|
participants = Gitlab::Markdown::ReferenceFilter::LazyReference.load(participants).uniq
|
||||||
|
|
||||||
if project
|
if project
|
||||||
participants.select! do |user|
|
participants.select! do |user|
|
||||||
user.can?(:read_project, project)
|
user.can?(:read_project, project)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
participants
|
participants
|
||||||
end
|
end
|
||||||
|
@ -64,12 +67,12 @@ module Participable
|
||||||
|
|
||||||
def participants_for(value, current_user = nil, project = nil)
|
def participants_for(value, current_user = nil, project = nil)
|
||||||
case value
|
case value
|
||||||
when User
|
when User, Gitlab::Markdown::ReferenceFilter::LazyReference
|
||||||
[value]
|
[value]
|
||||||
when Enumerable, ActiveRecord::Relation
|
when Enumerable, ActiveRecord::Relation
|
||||||
value.flat_map { |v| participants_for(v, current_user, project) }
|
value.flat_map { |v| participants_for(v, current_user, project) }
|
||||||
when Participable
|
when Participable
|
||||||
value.participants(current_user, project)
|
value.participants(current_user, project, load_lazy_references: false)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,17 +3,17 @@ require 'gitlab/markdown'
|
||||||
module Gitlab
|
module Gitlab
|
||||||
# Extract possible GFM references from an arbitrary String for further processing.
|
# Extract possible GFM references from an arbitrary String for further processing.
|
||||||
class ReferenceExtractor
|
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
|
@project = project
|
||||||
@current_user = current_user
|
@current_user = current_user
|
||||||
|
@load_lazy_references = load_lazy_references
|
||||||
end
|
end
|
||||||
|
|
||||||
def analyze(texts)
|
def analyze(text)
|
||||||
references.clear
|
references.clear
|
||||||
texts = Array(texts)
|
@text = Gitlab::Markdown.render_without_gfm(text)
|
||||||
@texts = texts.map { |text| Gitlab::Markdown.render_without_gfm(text) }
|
|
||||||
end
|
end
|
||||||
|
|
||||||
%i(user label issue merge_request snippet commit commit_range).each do |type|
|
%i(user label issue merge_request snippet commit commit_range).each do |type|
|
||||||
|
@ -29,7 +29,7 @@ module Gitlab
|
||||||
type = type.to_sym
|
type = type.to_sym
|
||||||
return references[type] if references.has_key?(type)
|
return references[type] if references.has_key?(type)
|
||||||
|
|
||||||
references[type] = pipeline_result(type).uniq
|
references[type] = pipeline_result(type)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -53,14 +53,15 @@ module Gitlab
|
||||||
}
|
}
|
||||||
|
|
||||||
pipeline = HTML::Pipeline.new([filter, Gitlab::Markdown::ReferenceGathererFilter], context)
|
pipeline = HTML::Pipeline.new([filter, Gitlab::Markdown::ReferenceGathererFilter], context)
|
||||||
|
result = pipeline.call(@text)
|
||||||
|
|
||||||
values = @texts.flat_map do |text|
|
values = result[:references][filter_type].uniq
|
||||||
result = pipeline.call(text)
|
|
||||||
|
|
||||||
result[:references][filter_type]
|
if @load_lazy_references
|
||||||
|
values = Gitlab::Markdown::ReferenceFilter::LazyReference.load(values).uniq
|
||||||
end
|
end
|
||||||
|
|
||||||
Gitlab::Markdown::ReferenceFilter::LazyReference.load(values)
|
values
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue