mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2024-12-28 19:24:10 +08:00
Add unique validation and ensure_uniqueness callback while moving folder
[SCI-5312]
This commit is contained in:
parent
88ed583a0c
commit
fbce70be0c
2 changed files with 85 additions and 2 deletions
|
@ -8,10 +8,11 @@ class ProjectFolder < ApplicationRecord
|
|||
validates :name,
|
||||
length: { minimum: Constants::NAME_MIN_LENGTH,
|
||||
maximum: Constants::NAME_MAX_LENGTH },
|
||||
uniqueness: { scope: :team_id, case_sensitive: false }
|
||||
uniqueness: { scope: %i(team_id parent_folder_id), case_sensitive: false }
|
||||
validate :parent_folder_team, if: -> { parent_folder.present? }
|
||||
|
||||
before_validation :inherit_team_from_parent_folder, on: :create, if: -> { parent_folder.present? }
|
||||
before_validation :ensure_uniqueness_name_on_moving, on: :update, if: -> { parent_folder_id_changed? }
|
||||
|
||||
belongs_to :team, inverse_of: :project_folders, touch: true
|
||||
belongs_to :parent_folder, class_name: 'ProjectFolder', optional: true
|
||||
|
@ -101,4 +102,20 @@ class ProjectFolder < ApplicationRecord
|
|||
|
||||
errors.add(:parent_folder, I18n.t('activerecord.errors.models.project_folder.attributes.parent_folder'))
|
||||
end
|
||||
|
||||
def ensure_uniqueness_name_on_moving
|
||||
return unless self.class.where(parent_folder: parent_folder).where('name ILIKE ?', name).any?
|
||||
|
||||
regex = /\((\d+)\)/
|
||||
max_number = self.class
|
||||
.where(parent_folder: parent_folder)
|
||||
.where('name ILIKE ?', "#{name} (%)")
|
||||
.order(name: :desc)
|
||||
.pluck(:name)
|
||||
.select { |s| s.match(regex) }
|
||||
.map { |s| s.match(regex)[1].to_i }
|
||||
.max || 0
|
||||
|
||||
self.name = name + " (#{max_number + 1})"
|
||||
end
|
||||
end
|
||||
|
|
|
@ -37,7 +37,7 @@ describe ProjectFolder, type: :model do
|
|||
.is_at_most(Constants::NAME_MAX_LENGTH))
|
||||
end
|
||||
it do
|
||||
expect(project_folder).to validate_uniqueness_of(:name).scoped_to(:team_id).case_insensitive
|
||||
expect(project_folder).to validate_uniqueness_of(:name).scoped_to(%i(team_id parent_folder_id)).case_insensitive
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -62,5 +62,71 @@ describe ProjectFolder, type: :model do
|
|||
expect { project_folder.save }.to(change { project_folder.team })
|
||||
end
|
||||
end
|
||||
|
||||
describe 'ensure_uniqueness_name_on_moving' do
|
||||
let(:team) { create :team }
|
||||
let(:parent_folder) { create :project_folder, team: team }
|
||||
|
||||
context 'when folder with same name already exists' do
|
||||
before do
|
||||
create :project_folder, name: 'FolderOne (some)', parent_folder: parent_folder, team: parent_folder.team
|
||||
create :project_folder, name: 'FolderOne (test)', parent_folder: parent_folder, team: parent_folder.team
|
||||
create :project_folder, name: 'FolderOne (111)', parent_folder: parent_folder, team: parent_folder.team
|
||||
create :project_folder, name: 'FolderOne (41)', parent_folder: parent_folder, team: parent_folder.team
|
||||
create :project_folder, name: 'FolderOne (1)', parent_folder: parent_folder, team: parent_folder.team
|
||||
create :project_folder, name: 'FolderOne (0)', parent_folder: parent_folder, team: parent_folder.team
|
||||
create :project_folder, name: 'FolderOne', parent_folder: parent_folder, team: parent_folder.team
|
||||
end
|
||||
|
||||
it 'appends number to name' do
|
||||
folder = create :project_folder, team: team, name: 'FolderOne'
|
||||
folder.update!(parent_folder: parent_folder)
|
||||
|
||||
expect(folder.name).to be_eql('FolderOne (112)')
|
||||
end
|
||||
|
||||
it 'keeps number if number is between already existing numbers, but is available' do
|
||||
folder = create :project_folder, team: team, name: 'FolderOne (40)'
|
||||
folder.update!(parent_folder: parent_folder)
|
||||
|
||||
expect(folder.name).to be_eql('FolderOne (40)')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when folder with same name does not exsits yet' do
|
||||
it do
|
||||
folder = create :project_folder, team: team, name: 'FolderOne'
|
||||
folder.update!(parent_folder: parent_folder)
|
||||
|
||||
expect(folder.name).to be_eql('FolderOne')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when new name parenthesises with text' do
|
||||
before do
|
||||
create :project_folder, name: 'FolderOne (some)', parent_folder: parent_folder, team: parent_folder.team
|
||||
end
|
||||
|
||||
it do
|
||||
folder = create :project_folder, team: team, name: 'FolderOne (some)'
|
||||
folder.update!(parent_folder: parent_folder)
|
||||
|
||||
expect(folder.name).to be_eql('FolderOne (some) (1)')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when new name parenthesises with numbers' do
|
||||
before do
|
||||
create :project_folder, name: 'FolderOne (1)', parent_folder: parent_folder, team: parent_folder.team
|
||||
end
|
||||
|
||||
it do
|
||||
folder = create :project_folder, team: team, name: 'FolderOne (1)'
|
||||
folder.update!(parent_folder: parent_folder)
|
||||
|
||||
expect(folder.name).to be_eql('FolderOne (1) (1)')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue