diff options
author | Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com> | 2017-01-05 20:20:12 +0300 |
---|---|---|
committer | Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com> | 2017-01-25 14:43:15 +0300 |
commit | 52c5f9c97f20529b608f5b47a7c361383ccadb54 (patch) | |
tree | a0eef9b8f387a9cc7c401b68d44ad4ee8183774e /app | |
parent | 51c4b20c48f29fe34fd1306f7a115f645eb9fb71 (diff) |
Add User#nested_groups and User#nested_projects methods
Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
Diffstat (limited to 'app')
-rw-r--r-- | app/models/concerns/routable.rb | 15 | ||||
-rw-r--r-- | app/models/namespace.rb | 4 | ||||
-rw-r--r-- | app/models/route.rb | 3 | ||||
-rw-r--r-- | app/models/user.rb | 9 | ||||
-rw-r--r-- | app/services/users/refresh_authorized_projects_service.rb | 3 |
5 files changed, 30 insertions, 4 deletions
diff --git a/app/models/concerns/routable.rb b/app/models/concerns/routable.rb index 1108a64c59e..2b93aa30c0f 100644 --- a/app/models/concerns/routable.rb +++ b/app/models/concerns/routable.rb @@ -60,6 +60,21 @@ module Routable joins(:route).where(wheres.join(' OR ')) end end + + # Builds a relation to find multiple objects that are nested under user membership + # + # Usage: + # + # Klass.member_descendants(1) + # + # Returns an ActiveRecord::Relation. + def member_descendants(user_id) + joins(:route). + joins("INNER JOIN routes r2 ON routes.path LIKE CONCAT(r2.path, '/%') + INNER JOIN members ON members.source_id = r2.source_id + AND members.source_type = r2.source_type"). + where('members.user_id = ?', user_id) + end end private diff --git a/app/models/namespace.rb b/app/models/namespace.rb index d3a4ddbb3bf..eb970dddd91 100644 --- a/app/models/namespace.rb +++ b/app/models/namespace.rb @@ -194,7 +194,7 @@ class Namespace < ActiveRecord::Base paths << path end - self.class.joins(:route).where('routes.path IN (?)', paths).order_id_asc + self.class.joins(:route).where('routes.path IN (?)', paths).reorder('routes.path ASC') else self.class.none end @@ -202,7 +202,7 @@ class Namespace < ActiveRecord::Base # Scopes the model on direct and indirect children of the record def descendants - self.class.joins(:route).where('routes.path LIKE ?', "#{route.path}/%").order_id_asc + self.class.joins(:route).where('routes.path LIKE ?', "#{route.path}/%").reorder('routes.path ASC') end private diff --git a/app/models/route.rb b/app/models/route.rb index ebd18dce737..dd171fdb069 100644 --- a/app/models/route.rb +++ b/app/models/route.rb @@ -15,8 +15,9 @@ class Route < ActiveRecord::Base # rubocop:disable Rails/FindEach Route.where('path LIKE ?', "#{path_was}/%").each do |route| # Note that update column skips validation and callbacks. - # We need this to avoid recursive call of rename_children method + # We need this to avoid recursive call of rename_descendants method route.update_column(:path, route.path.sub(path_was, path)) end + # rubocop:enable Rails/FindEach end end diff --git a/app/models/user.rb b/app/models/user.rb index 06dd98a3188..f294b9f77c1 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -439,6 +439,15 @@ class User < ActiveRecord::Base Group.where("namespaces.id IN (#{union.to_sql})") end + def nested_groups + Group.member_descendants(id) + end + + def nested_projects + Project.joins(:namespace).where('namespaces.parent_id IS NOT NULL'). + member_descendants(id) + end + def refresh_authorized_projects Users::RefreshAuthorizedProjectsService.new(self).execute end diff --git a/app/services/users/refresh_authorized_projects_service.rb b/app/services/users/refresh_authorized_projects_service.rb index 21ec1bd9e65..84d3c1c4373 100644 --- a/app/services/users/refresh_authorized_projects_service.rb +++ b/app/services/users/refresh_authorized_projects_service.rb @@ -119,7 +119,8 @@ module Users user.personal_projects.select("#{user.id} AS user_id, projects.id AS project_id, #{Gitlab::Access::MASTER} AS access_level"), user.groups_projects.select_for_project_authorization, user.projects.select_for_project_authorization, - user.groups.joins(:shared_projects).select_for_project_authorization + user.groups.joins(:shared_projects).select_for_project_authorization, + user.nested_projects.select_for_project_authorization ] Gitlab::SQL::Union.new(relations) |