diff options
author | Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com> | 2017-02-04 21:26:11 +0300 |
---|---|---|
committer | Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com> | 2017-02-08 20:14:29 +0300 |
commit | 2989192d1aa8051aa09164cd097418bd3063d4ad (patch) | |
tree | e277adf2535ac10ed338481ef092731ef84b27e1 /app | |
parent | bbb7fbcd02c9d9a8a6d6ca44d7ce668b80962c21 (diff) |
Store group and project full name and full path in routes table
Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
Diffstat (limited to 'app')
-rw-r--r-- | app/controllers/admin/dashboard_controller.rb | 4 | ||||
-rw-r--r-- | app/controllers/admin/groups_controller.rb | 2 | ||||
-rw-r--r-- | app/controllers/dashboard/groups_controller.rb | 2 | ||||
-rw-r--r-- | app/finders/groups_finder.rb | 2 | ||||
-rw-r--r-- | app/finders/projects_finder.rb | 2 | ||||
-rw-r--r-- | app/models/concerns/routable.rb | 66 | ||||
-rw-r--r-- | app/models/namespace.rb | 25 | ||||
-rw-r--r-- | app/models/project.rb | 43 | ||||
-rw-r--r-- | app/models/route.rb | 22 |
9 files changed, 104 insertions, 64 deletions
diff --git a/app/controllers/admin/dashboard_controller.rb b/app/controllers/admin/dashboard_controller.rb index c491e5c7550..8360ce08bdc 100644 --- a/app/controllers/admin/dashboard_controller.rb +++ b/app/controllers/admin/dashboard_controller.rb @@ -1,7 +1,7 @@ class Admin::DashboardController < Admin::ApplicationController def index - @projects = Project.limit(10) + @projects = Project.with_route.limit(10) @users = User.limit(10) - @groups = Group.limit(10) + @groups = Group.with_route.limit(10) end end diff --git a/app/controllers/admin/groups_controller.rb b/app/controllers/admin/groups_controller.rb index b7722a1d15d..578f2b8f038 100644 --- a/app/controllers/admin/groups_controller.rb +++ b/app/controllers/admin/groups_controller.rb @@ -2,7 +2,7 @@ class Admin::GroupsController < Admin::ApplicationController before_action :group, only: [:edit, :update, :destroy, :project_update, :members_update] def index - @groups = Group.with_statistics + @groups = Group.with_statistics.with_route @groups = @groups.sort(@sort = params[:sort]) @groups = @groups.search(params[:name]) if params[:name].present? @groups = @groups.page(params[:page]) diff --git a/app/controllers/dashboard/groups_controller.rb b/app/controllers/dashboard/groups_controller.rb index de6bc689bb7..0b7cf8167f0 100644 --- a/app/controllers/dashboard/groups_controller.rb +++ b/app/controllers/dashboard/groups_controller.rb @@ -1,5 +1,5 @@ class Dashboard::GroupsController < Dashboard::ApplicationController def index - @group_members = current_user.group_members.includes(:source).page(params[:page]) + @group_members = current_user.group_members.includes(source: :route).page(params[:page]) end end diff --git a/app/finders/groups_finder.rb b/app/finders/groups_finder.rb index 4e43f42e9e1..d932a17883f 100644 --- a/app/finders/groups_finder.rb +++ b/app/finders/groups_finder.rb @@ -2,7 +2,7 @@ class GroupsFinder < UnionFinder def execute(current_user = nil) segments = all_groups(current_user) - find_union(segments, Group).order_id_desc + find_union(segments, Group).with_route.order_id_desc end private diff --git a/app/finders/projects_finder.rb b/app/finders/projects_finder.rb index c7911736812..18ec45f300d 100644 --- a/app/finders/projects_finder.rb +++ b/app/finders/projects_finder.rb @@ -3,7 +3,7 @@ class ProjectsFinder < UnionFinder segments = all_projects(current_user) segments.map! { |s| s.where(id: project_ids_relation) } if project_ids_relation - find_union(segments, Project) + find_union(segments, Project).with_route end private diff --git a/app/models/concerns/routable.rb b/app/models/concerns/routable.rb index 2b93aa30c0f..9f6d215ceb3 100644 --- a/app/models/concerns/routable.rb +++ b/app/models/concerns/routable.rb @@ -1,5 +1,5 @@ # Store object full path in separate table for easy lookup and uniq validation -# Object must have path db field and respond to full_path and full_path_changed? methods. +# Object must have name and path db fields and respond to parent and parent_changed? methods. module Routable extend ActiveSupport::Concern @@ -9,7 +9,13 @@ module Routable validates_associated :route validates :route, presence: true - before_validation :update_route_path, if: :full_path_changed? + scope :with_route, -> { includes(:route) } + + before_validation do + if full_path_changed? || full_name_changed? + prepare_route + end + end end class_methods do @@ -77,10 +83,62 @@ module Routable end end + def full_name + if route && route.name.present? + @full_name ||= route.name + else + update_route if persisted? + + build_full_name + end + end + + def full_path + if route && route.path.present? + @full_path ||= route.path + else + update_route if persisted? + + build_full_path + end + end + private - def update_route_path + def full_name_changed? + name_changed? || parent_changed? + end + + def full_path_changed? + path_changed? || parent_changed? + end + + def build_full_name + if parent && name + parent.human_name + ' / ' + name + else + name + end + end + + def build_full_path + if parent && path + parent.full_path + '/' + path + else + path + end + end + + def update_route + prepare_route + route.save + end + + def prepare_route route || build_route(source: self) - route.path = full_path + route.path = build_full_path + route.name = build_full_name + @full_path = nil + @full_name = nil end end diff --git a/app/models/namespace.rb b/app/models/namespace.rb index c5713fb7818..c2554317ad3 100644 --- a/app/models/namespace.rb +++ b/app/models/namespace.rb @@ -170,27 +170,10 @@ class Namespace < ActiveRecord::Base Gitlab.config.lfs.enabled end - def full_path - if parent - parent.full_path + '/' + path - else - path - end - end - def shared_runners_enabled? projects.with_shared_runners.any? end - def full_name - @full_name ||= - if parent - parent.full_name + ' / ' + name - else - name - end - end - # Scopes the model on ancestors of the record def ancestors if parent_id @@ -217,6 +200,10 @@ class Namespace < ActiveRecord::Base [owner_id] end + def parent_changed? + parent_id_changed? + end + private def repository_storage_paths @@ -255,10 +242,6 @@ class Namespace < ActiveRecord::Base find_each(&:refresh_members_authorized_projects) end - def full_path_changed? - path_changed? || parent_id_changed? - end - def remove_exports! Gitlab::Popen.popen(%W(find #{export_path} -not -path #{export_path} -delete)) end diff --git a/app/models/project.rb b/app/models/project.rb index b45f22d94d9..c17bcedf7b2 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -228,7 +228,12 @@ class Project < ActiveRecord::Base scope :with_project_feature, -> { joins('LEFT JOIN project_features ON projects.id = project_features.project_id') } scope :with_statistics, -> { includes(:statistics) } scope :with_shared_runners, -> { where(shared_runners_enabled: true) } - scope :inside_path, ->(path) { joins(:route).where('routes.path LIKE ?', "#{path}/%") } + scope :inside_path, ->(path) do + # We need routes alias rs for JOIN so it does not conflict with + # includes(:route) which we use in ProjectsFinder. + joins("INNER JOIN routes rs ON rs.source_id = projects.id AND rs.source_type = 'Project'"). + where('rs.path LIKE ?', "#{path}/%") + end # "enabled" here means "not disabled". It includes private features! scope :with_feature_enabled, ->(feature) { @@ -810,26 +815,6 @@ class Project < ActiveRecord::Base end end - def name_with_namespace - @name_with_namespace ||= begin - if namespace - namespace.human_name + ' / ' + name - else - name - end - end - end - alias_method :human_name, :name_with_namespace - - def full_path - if namespace && path - namespace.full_path + '/' + path - else - path - end - end - alias_method :path_with_namespace, :full_path - def execute_hooks(data, hooks_scope = :push_hooks) hooks.send(hooks_scope).each do |hook| hook.async_execute(data, hooks_scope.to_s) @@ -1328,6 +1313,18 @@ class Project < ActiveRecord::Base map.public_path_for_source_path(path) end + def parent + namespace + end + + def parent_changed? + namespace_id_changed? + end + + alias_method :name_with_namespace, :full_name + alias_method :human_name, :full_name + alias_method :path_with_namespace, :full_path + private def cross_namespace_reference?(from) @@ -1366,10 +1363,6 @@ class Project < ActiveRecord::Base raise BoardLimitExceeded, 'Number of permitted boards exceeded' if boards.size >= NUMBER_OF_PERMITTED_BOARDS end - def full_path_changed? - path_changed? || namespace_id_changed? - end - def update_project_statistics stats = statistics || build_statistics stats.update(namespace_id: namespace_id) diff --git a/app/models/route.rb b/app/models/route.rb index dd171fdb069..4eec3e73d5b 100644 --- a/app/models/route.rb +++ b/app/models/route.rb @@ -8,16 +8,22 @@ class Route < ActiveRecord::Base presence: true, uniqueness: { case_sensitive: false } - after_update :rename_descendants, if: :path_changed? + after_update :rename_descendants def rename_descendants - # We update each row separately because MySQL does not have regexp_replace. - # 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_descendants method - route.update_column(:path, route.path.sub(path_was, path)) + if path_changed? || name_changed? + descendants = Route.where('path LIKE ?', "#{path_was}/%") + + descendants.each do |route| + attributes = { + path: route.path.sub(path_was, path), + name: route.name.sub(name_was, name) + } + + # Note that update_columns skips validation and callbacks. + # We need this to avoid recursive call of rename_descendants method + route.update_columns(attributes) + end end - # rubocop:enable Rails/FindEach end end |