Commit ab5d5b7e authored by Bob Van Landuyt's avatar Bob Van Landuyt

Make sure all queries are limited to the page size

And fix some pagination bugs
parent 7a3ba8e9
...@@ -10,23 +10,20 @@ class GroupDescendantsFinder ...@@ -10,23 +10,20 @@ class GroupDescendantsFinder
end end
def execute def execute
Kaminari.paginate_array(children) # The children array might be extended with the ancestors of projects when
# filtering. In that case, take the maximum so the aray does not get limited
# Otherwise, allow paginating through the search results
#
total_count = [children.size, subgroup_count + project_count].max
Kaminari.paginate_array(children, total_count: total_count)
end end
def subgroup_count def subgroup_count
@subgroup_count ||= if defined?(@children) @subgroup_count ||= subgroups.count
children.count { |child| child.is_a?(Group) }
else
subgroups.count
end
end end
def project_count def project_count
@project_count ||= if defined?(@children) @project_count ||= projects.count
children.count { |child| child.is_a?(Project) }
else
projects.count
end
end end
private private
...@@ -57,14 +54,19 @@ class GroupDescendantsFinder ...@@ -57,14 +54,19 @@ class GroupDescendantsFinder
member_count member_count
] ]
subgroups_with_counts = subgroups.with_route.select(group_selects) subgroups_with_counts = subgroups.with_route.page(params[:page]).per(per_page).select(group_selects)
group_page_count = subgroups_with_counts.total_pages
subgroup_page = subgroups_with_counts.current_page
paginated_projects = projects.with_route.page(subgroup_page - group_page_count)
.per(per_page - subgroups_with_counts.size)
if params[:filter] if params[:filter]
ancestors_for_project_search = ancestors_for_groups(Group.where(id: projects_matching_filter.select(:namespace_id))) ancestors_for_project_search = ancestors_for_groups(Group.where(id: paginated_projects.select(:namespace_id)))
subgroups_with_counts = ancestors_for_project_search.with_route.select(group_selects) | subgroups_with_counts subgroups_with_counts = ancestors_for_project_search.with_route.select(group_selects) | subgroups_with_counts
end end
@children = subgroups_with_counts + projects.with_route @children = subgroups_with_counts + paginated_projects
end end
def direct_child_groups def direct_child_groups
...@@ -110,7 +112,7 @@ class GroupDescendantsFinder ...@@ -110,7 +112,7 @@ class GroupDescendantsFinder
else else
direct_child_groups direct_child_groups
end end
groups.sort(params[:sort]) groups.order_by(sort)
end end
def projects_for_user def projects_for_user
...@@ -123,7 +125,7 @@ class GroupDescendantsFinder ...@@ -123,7 +125,7 @@ class GroupDescendantsFinder
def projects_matching_filter def projects_matching_filter
projects_for_user.search(params[:filter]) projects_for_user.search(params[:filter])
.where(namespace: all_descendant_groups) .where(namespace: all_visible_descendant_groups)
end end
def projects def projects
...@@ -134,6 +136,14 @@ class GroupDescendantsFinder ...@@ -134,6 +136,14 @@ class GroupDescendantsFinder
else else
direct_child_projects direct_child_projects
end end
projects.sort(params[:sort]) projects.order_by(sort)
end
def sort
params.fetch(:sort, 'id_asc')
end
def per_page
params.fetch(:per_page, Kaminari.config.default_per_page)
end end
end end
...@@ -174,18 +174,18 @@ describe GroupsController do ...@@ -174,18 +174,18 @@ describe GroupsController do
end end
context 'with subgroups and projects', :nested_groups do context 'with subgroups and projects', :nested_groups do
let!(:first_page_subgroups) { create_list(:group, Kaminari.config.default_per_page, parent: group) }
let!(:other_subgroup) { create(:group, :public, parent: group) } let!(:other_subgroup) { create(:group, :public, parent: group) }
let!(:project) { create(:project, :public, namespace: group) } let!(:project) { create(:project, :public, namespace: group) }
let!(:first_page_subgroups) { create_list(:group, Kaminari.config.default_per_page, parent: group) }
it 'contains all subgroups' do it 'contains all subgroups' do
get :children, id: group.to_param, sort: 'id_desc', format: :json get :children, id: group.to_param, sort: 'id_asc', format: :json
expect(assigns(:children)).to contain_exactly(*first_page_subgroups) expect(assigns(:children)).to contain_exactly(*first_page_subgroups)
end end
it 'contains the project and group on the second page' do it 'contains the project and group on the second page' do
get :children, id: group.to_param, sort: 'id_desc', page: 2, format: :json get :children, id: group.to_param, sort: 'id_asc', page: 2, format: :json
expect(assigns(:children)).to contain_exactly(other_subgroup, project) expect(assigns(:children)).to contain_exactly(other_subgroup, project)
end 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