diff options
author | Bob Van Landuyt <bob@vanlanduyt.co> | 2017-10-05 10:38:05 +0200 |
---|---|---|
committer | Bob Van Landuyt <bob@vanlanduyt.co> | 2017-10-05 13:12:40 +0200 |
commit | e013d39875bbf5f6e11fda627a8dab045023d59e (patch) | |
tree | 0d671d2a4c1e9600eea6f86fb046296bbb6dd218 | |
parent | 951abe2b2efc3a208ceea46d9c1c47d3d253ff63 (diff) | |
download | gitlab-ce-e013d39875bbf5f6e11fda627a8dab045023d59e.tar.gz |
Optimize finding a membership for a user to avoid extra queries
-rw-r--r-- | app/models/user.rb | 9 | ||||
-rw-r--r-- | app/serializers/group_child_entity.rb | 16 | ||||
-rw-r--r-- | spec/serializers/group_child_entity_spec.rb | 4 |
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 |