Commit 7fd7221b authored by Mark Chao's avatar Mark Chao

Merge branch '329587-reuse-bulkmemberaccessload-for-group' into 'master'

Reuse BulkMemberAccessLoad on groups [RUN AS-IF-FOSS]

See merge request gitlab-org/gitlab!62226
parents 8375fd59 daa4c18e
......@@ -25,7 +25,6 @@ class Groups::GroupMembersController < Groups::ApplicationController
helper_method :can_manage_members?
def index
preload_max_access
@sort = params[:sort].presence || sort_value_name
@members = GroupMembersFinder
......@@ -54,14 +53,6 @@ class Groups::GroupMembersController < Groups::ApplicationController
private
def preload_max_access
return unless current_user
# this allows the can? against admin type queries in this action to
# only perform the query once, even if it is cached
current_user.max_access_for_group[@group.id] = @group.max_member_access(current_user)
end
def can_manage_members?
strong_memoize(:can_manage_members) do
can?(current_user, :admin_group_member, @group)
......
......@@ -17,6 +17,7 @@ class Group < Namespace
include GroupAPICompatibility
include EachBatch
include HasTimelogsReport
include BulkMemberAccessLoad
ACCESS_REQUEST_APPROVERS_TO_BE_NOTIFIED_LIMIT = 10
......@@ -569,24 +570,8 @@ class Group < Namespace
def max_member_access_for_user(user, only_concrete_membership: false)
return GroupMember::NO_ACCESS unless user
return GroupMember::OWNER if user.can_admin_all_resources? && !only_concrete_membership
# Use the preloaded value that exists instead of performing the db query again(cached or not).
# Groups::GroupMembersController#preload_max_access makes use of this by
# calling Group#max_member_access. This helps when we have a process
# that may query this multiple times from the outside through a policy query
# like the GroupPolicy#lookup_access_level! does as a condition for any role
return user.max_access_for_group[id] if user.max_access_for_group[id]
max_member_access(user)
end
def max_member_access(user)
max_member_access = members_with_parents
.where(user_id: user)
.reorder(access_level: :desc)
.first
&.access_level
max_member_access || GroupMember::NO_ACCESS
max_member_access([user.id])[user.id]
end
def mattermost_team_params
......@@ -730,6 +715,12 @@ class Group < Namespace
private
def max_member_access(user_ids)
max_member_access_for_resource_ids(User, user_ids) do |user_ids|
members_with_parents.where(user_id: user_ids).group(:user_id).maximum(:access_level)
end
end
def update_two_factor_requirement
return unless saved_change_to_require_two_factor_authentication? || saved_change_to_two_factor_grace_period?
......
......@@ -99,12 +99,6 @@ class User < ApplicationRecord
# Virtual attribute for impersonator
attr_accessor :impersonator
attr_writer :max_access_for_group
def max_access_for_group
@max_access_for_group ||= {}
end
#
# Relations
#
......
......@@ -20,15 +20,15 @@ RSpec.describe Groups::GroupMembersController do
let!(:invited) { create(:group_member, :invited, :developer, group: group) }
let!(:requested) { create(:group_member, :access_request, group: group) }
it 'records queries', :use_sql_query_cache do
it 'records queries', :request_store, :use_sql_query_cache do
get :index, params: { group_id: group }
control = ActiveRecord::QueryRecorder.new(skip_cached: false) { get :index, params: { group_id: group } }
create_list(:group_member, 5, group: group, created_by: user)
create_list(:group_member, 5, :invited, group: group, created_by: user)
create_list(:group_member, 5, :access_request, group: group)
# locally 47 vs 52 GDK vs 57 CI
unresolved_n_plus_ones = 5 # still have a few queries created by can_update/can_remove that should be reduced
# locally 39 vs 43 GDK vs 48 CI
unresolved_n_plus_ones = 4 # still have a few queries created by can_update/can_remove that could be reduced
multiple_members_threshold = 5 # GDK vs CI difference
expect do
......
......@@ -32,14 +32,6 @@ RSpec.describe Groups::GroupMembersController do
sign_in(user)
end
it 'assigns max_access_for_group' do
allow(controller).to receive(:current_user).and_return(user)
get :index, params: { group_id: group }
expect(user.max_access_for_group[group.id]).to eq(Gitlab::Access::OWNER)
end
it 'assigns invited members' do
get :index, params: { group_id: group }
......
This diff is collapsed.
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