summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Van Landuyt <bob@vanlanduyt.co>2017-10-05 10:38:05 +0200
committerBob Van Landuyt <bob@vanlanduyt.co>2017-10-05 13:12:40 +0200
commite013d39875bbf5f6e11fda627a8dab045023d59e (patch)
tree0d671d2a4c1e9600eea6f86fb046296bbb6dd218
parent951abe2b2efc3a208ceea46d9c1c47d3d253ff63 (diff)
downloadgitlab-ce-e013d39875bbf5f6e11fda627a8dab045023d59e.tar.gz
Optimize finding a membership for a user to avoid extra queries
-rw-r--r--app/models/user.rb9
-rw-r--r--app/serializers/group_child_entity.rb16
-rw-r--r--spec/serializers/group_child_entity_spec.rb4
3 files changed, 22 insertions, 7 deletions
diff --git a/app/models/user.rb b/app/models/user.rb
index 4e71a3e11c2..8ce0fecc34d 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -1073,6 +1073,15 @@ class User < ActiveRecord::Base
super
end
+ # Get the membership for an object without loading the source of the membership
+ #
+ # This loads the entire `members` relation of the user, used on `current_user`
+ def membership_for_object(object)
+ members.sort('access_level_asc').detect do |member|
+ object.is_a?(member.source_type.constantize) && member.source_id == object.id
+ end
+ end
+
protected
# override, from Devise::Validatable
diff --git a/app/serializers/group_child_entity.rb b/app/serializers/group_child_entity.rb
index 6cfdd93e9bb..b602a17156f 100644
--- a/app/serializers/group_child_entity.rb
+++ b/app/serializers/group_child_entity.rb
@@ -40,9 +40,7 @@ class GroupChildEntity < Grape::Entity
end
def permission
- return unless request&.current_user
-
- request.current_user.members.find_by(source: object)&.human_access
+ membership&.human_access
end
# Project only attributes
@@ -55,11 +53,11 @@ class GroupChildEntity < Grape::Entity
unless: lambda { |_instance, _options| project? }
def leave_path
- leave_group_group_members_path(object)
+ leave_group_members_path(object)
end
def can_leave
- if membership = object.members_and_requesters.find_by(user: request.current_user)
+ if membership
can?(request.current_user, :destroy_group_member, membership)
else
false
@@ -73,4 +71,12 @@ class GroupChildEntity < Grape::Entity
def number_users_with_delimiter
number_with_delimiter(object.member_count)
end
+
+ private
+
+ def membership
+ return unless request.current_user
+
+ @membership ||= request.current_user.membership_for_object(object)
+ end
end
diff --git a/spec/serializers/group_child_entity_spec.rb b/spec/serializers/group_child_entity_spec.rb
index 54a1b1846e1..64000385781 100644
--- a/spec/serializers/group_child_entity_spec.rb
+++ b/spec/serializers/group_child_entity_spec.rb
@@ -34,7 +34,7 @@ describe GroupChildEntity do
end
describe 'for a project' do
- set(:object) do
+ let(:object) do
create(:project, :with_avatar,
description: 'Awesomeness')
end
@@ -55,7 +55,7 @@ describe GroupChildEntity do
end
describe 'for a group', :nested_groups do
- set(:object) do
+ let(:object) do
create(:group, :nested, :with_avatar,
description: 'Awesomeness')
end