Commit 5a210dd8 authored by Małgorzata Ksionek's avatar Małgorzata Ksionek

Fix slow group loading on forking page

By preloading associations and loading membership in controller
parent 86abb0af
......@@ -43,9 +43,10 @@ class Projects::ForksController < Projects::ApplicationController
end
format.json do
namespaces = fork_service.valid_fork_targets - [current_user.namespace, project.namespace]
namespaces = load_namespaces_with_associations - [project.namespace]
render json: {
namespaces: ForkNamespaceSerializer.new.represent(namespaces, project: project, current_user: current_user)
namespaces: ForkNamespaceSerializer.new.represent(namespaces, project: project, current_user: current_user, memberships: memberships_hash)
}
end
end
......@@ -100,6 +101,17 @@ class Projects::ForksController < Projects::ApplicationController
def whitelist_query_limiting
Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab-foss/issues/42335')
end
def load_namespaces_with_associations
fork_service.valid_fork_targets(only_groups: true).preload(:route)
end
def memberships_hash
current_user.members.inject({}) do |memberships, member|
memberships[member.source_id] = member
memberships
end
end
end
Projects::ForksController.prepend_if_ee('EE::Projects::ForksController')
......@@ -7,8 +7,10 @@ class ForkTargetsFinder
end
# rubocop: disable CodeReuse/ActiveRecord
def execute
::Namespace.where(id: user.manageable_namespaces).sort_by_type
def execute(options = {})
return ::Namespace.where(id: user.manageable_namespaces).sort_by_type unless options[:only_groups]
::Group.where(id: user.manageable_namespaces)
end
# rubocop: enable CodeReuse/ActiveRecord
......
......@@ -19,7 +19,7 @@ class ForkNamespaceEntity < Grape::Entity
end
expose :permission do |namespace, options|
membership(options[:current_user], namespace)&.human_access
membership(options[:current_user], namespace, options[:memberships])&.human_access
end
expose :relative_path do |namespace|
......@@ -37,10 +37,10 @@ class ForkNamespaceEntity < Grape::Entity
private
# rubocop: disable CodeReuse/ActiveRecord
def membership(user, object)
def membership(user, object, memberships)
return unless user
@membership ||= user.members.find_by(source: object)
memberships[object.id]
end
# rubocop: enable CodeReuse/ActiveRecord
......
......@@ -10,8 +10,8 @@ module Projects
forked_project
end
def valid_fork_targets
@valid_fork_targets ||= ForkTargetsFinder.new(@project, current_user).execute
def valid_fork_targets(options = {})
@valid_fork_targets ||= ForkTargetsFinder.new(@project, current_user).execute(options)
end
def valid_fork_target?(namespace = target_namespace)
......
......@@ -11,6 +11,11 @@ module EE
def load_forks
super.with_compliance_framework_settings
end
override :load_namespaces_with_associations
def load_namespaces_with_associations
super.preload(:deletion_schedule)
end
end
end
end
......@@ -7,7 +7,7 @@ module EE
override :execute
# rubocop: disable CodeReuse/ActiveRecord
def execute
def execute(options = {})
targets = super
root_group = project.group&.root_ancestor
......
......@@ -35,5 +35,13 @@ RSpec.describe ForkTargetsFinder do
it 'returns all user manageable namespaces' do
expect(finder.execute).to match_array([user.namespace, maintained_group, owned_group, project.namespace])
end
it 'returns only groups when only_groups option is passed' do
expect(finder.execute(only_groups: true)).to match_array([maintained_group, owned_group, project.namespace])
end
it 'returns groups relation when only_groups option is passed' do
expect(finder.execute(only_groups: true)).to include(a_kind_of(Group))
end
end
end
......@@ -10,12 +10,19 @@ RSpec.describe ForkNamespaceEntity do
let_it_be(:project) { create(:project) }
let(:namespace) { create(:group, :with_avatar, description: 'test') }
let(:entity) { described_class.new(namespace, current_user: user, project: project) }
let(:memberships) do
user.members.inject({}) do |memberships, member|
memberships[member.source_id] = member
memberships
end
end
let(:entity) { described_class.new(namespace, current_user: user, project: project, memberships: memberships) }
subject(:json) { entity.as_json }
before do
project.add_maintainer(user)
namespace.add_developer(user)
end
it 'renders json' do
......@@ -52,7 +59,6 @@ RSpec.describe ForkNamespaceEntity do
end
it 'exposes human readable permission level' do
namespace.add_developer(user)
expect(json[:permission]).to eql 'Developer'
end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment