Refactor Namespace code related to nested groups
Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
This commit is contained in:
parent
4b43126d08
commit
51c4b20c48
|
@ -14,7 +14,7 @@ module GroupsHelper
|
||||||
def group_title(group, name = nil, url = nil)
|
def group_title(group, name = nil, url = nil)
|
||||||
full_title = ''
|
full_title = ''
|
||||||
|
|
||||||
group.parents.each do |parent|
|
group.ancestors.each do |parent|
|
||||||
full_title += link_to(simple_sanitize(parent.name), group_path(parent))
|
full_title += link_to(simple_sanitize(parent.name), group_path(parent))
|
||||||
full_title += ' / '.html_safe
|
full_title += ' / '.html_safe
|
||||||
end
|
end
|
||||||
|
|
|
@ -201,7 +201,7 @@ class Group < Namespace
|
||||||
end
|
end
|
||||||
|
|
||||||
def members_with_parents
|
def members_with_parents
|
||||||
GroupMember.where(requested_at: nil, source_id: parents.map(&:id).push(id))
|
GroupMember.where(requested_at: nil, source_id: ancestors.map(&:id).push(id))
|
||||||
end
|
end
|
||||||
|
|
||||||
def users_with_parents
|
def users_with_parents
|
||||||
|
|
|
@ -183,8 +183,26 @@ class Namespace < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def parents
|
# Scopes the model on ancestors of the record
|
||||||
@parents ||= parent ? parent.parents + [parent] : []
|
def ancestors
|
||||||
|
if parent_id
|
||||||
|
path = route.path
|
||||||
|
paths = []
|
||||||
|
|
||||||
|
until path.blank?
|
||||||
|
path = path.rpartition('/').first
|
||||||
|
paths << path
|
||||||
|
end
|
||||||
|
|
||||||
|
self.class.joins(:route).where('routes.path IN (?)', paths).order_id_asc
|
||||||
|
else
|
||||||
|
self.class.none
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# 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
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
|
@ -8,9 +8,9 @@ class Route < ActiveRecord::Base
|
||||||
presence: true,
|
presence: true,
|
||||||
uniqueness: { case_sensitive: false }
|
uniqueness: { case_sensitive: false }
|
||||||
|
|
||||||
after_update :rename_children, if: :path_changed?
|
after_update :rename_descendants, if: :path_changed?
|
||||||
|
|
||||||
def rename_children
|
def rename_descendants
|
||||||
# We update each row separately because MySQL does not have regexp_replace.
|
# We update each row separately because MySQL does not have regexp_replace.
|
||||||
# rubocop:disable Rails/FindEach
|
# rubocop:disable Rails/FindEach
|
||||||
Route.where('path LIKE ?', "#{path_was}/%").each do |route|
|
Route.where('path LIKE ?', "#{path_was}/%").each do |route|
|
||||||
|
|
|
@ -5,6 +5,8 @@ describe Namespace, models: true do
|
||||||
|
|
||||||
it { is_expected.to have_many :projects }
|
it { is_expected.to have_many :projects }
|
||||||
it { is_expected.to have_many :project_statistics }
|
it { is_expected.to have_many :project_statistics }
|
||||||
|
it { is_expected.to belong_to :parent }
|
||||||
|
it { is_expected.to have_many :children }
|
||||||
|
|
||||||
it { is_expected.to validate_presence_of(:name) }
|
it { is_expected.to validate_presence_of(:name) }
|
||||||
it { is_expected.to validate_uniqueness_of(:name).scoped_to(:parent_id) }
|
it { is_expected.to validate_uniqueness_of(:name).scoped_to(:parent_id) }
|
||||||
|
@ -182,17 +184,31 @@ describe Namespace, models: true do
|
||||||
it { expect(nested_group.full_name).to eq("#{group.name} / #{nested_group.name}") }
|
it { expect(nested_group.full_name).to eq("#{group.name} / #{nested_group.name}") }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#parents' do
|
describe '#ancestors' do
|
||||||
let(:group) { create(:group) }
|
let(:group) { create(:group) }
|
||||||
let(:nested_group) { create(:group, parent: group) }
|
let(:nested_group) { create(:group, parent: group) }
|
||||||
let(:deep_nested_group) { create(:group, parent: nested_group) }
|
let(:deep_nested_group) { create(:group, parent: nested_group) }
|
||||||
let(:very_deep_nested_group) { create(:group, parent: deep_nested_group) }
|
let(:very_deep_nested_group) { create(:group, parent: deep_nested_group) }
|
||||||
|
|
||||||
it 'returns the correct parents' do
|
it 'returns the correct ancestors' do
|
||||||
expect(very_deep_nested_group.parents).to eq([group, nested_group, deep_nested_group])
|
expect(very_deep_nested_group.ancestors).to eq([group, nested_group, deep_nested_group])
|
||||||
expect(deep_nested_group.parents).to eq([group, nested_group])
|
expect(deep_nested_group.ancestors).to eq([group, nested_group])
|
||||||
expect(nested_group.parents).to eq([group])
|
expect(nested_group.ancestors).to eq([group])
|
||||||
expect(group.parents).to eq([])
|
expect(group.ancestors).to eq([])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#descendants' do
|
||||||
|
let!(:group) { create(:group) }
|
||||||
|
let!(:nested_group) { create(:group, parent: group) }
|
||||||
|
let!(:deep_nested_group) { create(:group, parent: nested_group) }
|
||||||
|
let!(:very_deep_nested_group) { create(:group, parent: deep_nested_group) }
|
||||||
|
|
||||||
|
it 'returns the correct descendants' do
|
||||||
|
expect(very_deep_nested_group.descendants.to_a).to eq([])
|
||||||
|
expect(deep_nested_group.descendants.to_a).to eq([very_deep_nested_group])
|
||||||
|
expect(nested_group.descendants.to_a).to eq([deep_nested_group, very_deep_nested_group])
|
||||||
|
expect(group.descendants.to_a).to eq([nested_group, deep_nested_group, very_deep_nested_group])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -14,7 +14,7 @@ describe Route, models: true do
|
||||||
it { is_expected.to validate_uniqueness_of(:path) }
|
it { is_expected.to validate_uniqueness_of(:path) }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#rename_children' do
|
describe '#rename_descendants' do
|
||||||
let!(:nested_group) { create(:group, path: "test", parent: group) }
|
let!(:nested_group) { create(:group, path: "test", parent: group) }
|
||||||
let!(:deep_nested_group) { create(:group, path: "foo", parent: nested_group) }
|
let!(:deep_nested_group) { create(:group, path: "foo", parent: nested_group) }
|
||||||
let!(:similar_group) { create(:group, path: 'gitlab-org') }
|
let!(:similar_group) { create(:group, path: 'gitlab-org') }
|
||||||
|
|
Loading…
Reference in New Issue