gitlab-org--gitlab-foss/app/finders/group_projects_finder.rb
Yorick Peterse 77d4546eda
Reduce queries in GroupProjectsFinder
GroupProjectsFinder#collection_with_user would run the following code:

    if group.users.include?(current_user)

When running this code for multiple groups this would result in one
query being executed for every group.

This commit simple removes the entire "if" statement with the code of
the "else" statement. This ensures both paths use the same code, and
removes the need for explicitly checking if a user is a member of the
group.
2018-05-28 13:52:37 +02:00

96 lines
2.1 KiB
Ruby

# GroupProjectsFinder
#
# Used to filter Projects by set of params
#
# Arguments:
# current_user - which user use
# project_ids_relation: int[] - project ids to use
# group
# options:
# only_owned: boolean
# only_shared: boolean
# params:
# sort: string
# visibility_level: int
# tags: string[]
# personal: boolean
# search: string
# non_archived: boolean
#
class GroupProjectsFinder < ProjectsFinder
attr_reader :group, :options
def initialize(group:, params: {}, options: {}, current_user: nil, project_ids_relation: nil)
super(params: params, current_user: current_user, project_ids_relation: project_ids_relation)
@group = group
@options = options
end
private
def init_collection
projects = if current_user
collection_with_user
else
collection_without_user
end
union(projects)
end
def collection_with_user
if only_shared?
[shared_projects.public_or_visible_to_user(current_user)]
elsif only_owned?
[owned_projects.public_or_visible_to_user(current_user)]
else
[
owned_projects.public_or_visible_to_user(current_user),
shared_projects.public_or_visible_to_user(current_user)
]
end
end
def collection_without_user
if only_shared?
[shared_projects.public_only]
elsif only_owned?
[owned_projects.public_only]
else
[shared_projects.public_only, owned_projects.public_only]
end
end
def union(items)
if items.one?
items.first
else
find_union(items, Project)
end
end
def only_owned?
options.fetch(:only_owned, false)
end
def only_shared?
options.fetch(:only_shared, false)
end
# subgroups are supported only for owned projects not for shared
def include_subgroups?
options.fetch(:include_subgroups, false)
end
def owned_projects
if include_subgroups?
Project.where(namespace_id: group.self_and_descendants.select(:id))
else
group.projects
end
end
def shared_projects
group.shared_projects
end
end