diff --git a/app/controllers/project_settings/versions_controller.rb b/app/controllers/project_settings/versions_controller.rb index 25c18f994ca..b093c8cd91a 100644 --- a/app/controllers/project_settings/versions_controller.rb +++ b/app/controllers/project_settings/versions_controller.rb @@ -1,4 +1,5 @@ #-- encoding: UTF-8 + #-- copyright # OpenProject is an open source project management software. # Copyright (C) 2012-2020 the OpenProject GmbH @@ -31,7 +32,7 @@ class ProjectSettings::VersionsController < ProjectSettingsController menu_item :settings_versions def show - @versions = @project.shared_versions.merge(Versions::Scopes::OrderBySemverName.fetch) + @versions = @project.shared_versions.order_by_semver_name render template: 'project_settings/versions' end diff --git a/app/models/project/status.rb b/app/models/project/status.rb index 0bfa4a63153..23d82e09afd 100644 --- a/app/models/project/status.rb +++ b/app/models/project/status.rb @@ -31,6 +31,8 @@ class Project::Status < ActiveRecord::Base belongs_to :project + self.table_name = 'project_statuses' + validates :project, presence: true, uniqueness: true diff --git a/app/models/scopes/scoped.rb b/app/models/scopes/scoped.rb new file mode 100644 index 00000000000..e4cf762c60b --- /dev/null +++ b/app/models/scopes/scoped.rb @@ -0,0 +1,45 @@ +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) 2012-2020 the OpenProject GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2017 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See docs/COPYRIGHT.rdoc for more details. +#++ + +module Scopes::Scoped + extend ActiveSupport::Concern + + included do + base_namespace = name.pluralize.constantize + + base_namespace::Scopes.constants.each do |scope| + scope_class = base_namespace::Scopes.const_get(scope) + + define_singleton_method(scope.to_s.underscore) do + scope_class.fetch + end + end + rescue NameError + # Do nothing as there apparently are no matching scopes defined + end +end diff --git a/app/models/version.rb b/app/models/version.rb index 431934a147b..1312b0bbbc3 100644 --- a/app/models/version.rb +++ b/app/models/version.rb @@ -30,6 +30,7 @@ class Version < ActiveRecord::Base include ::Versions::ProjectSharing + include ::Scopes::Scoped belongs_to :project has_many :fixed_issues, class_name: 'WorkPackage', foreign_key: 'fixed_version_id', dependent: :nullify diff --git a/app/models/versions/scopes/order_by_semver_name.rb b/app/models/versions/scopes/order_by_semver_name.rb index 80bfbe8735c..4bcbfc5d07b 100644 --- a/app/models/versions/scopes/order_by_semver_name.rb +++ b/app/models/versions/scopes/order_by_semver_name.rb @@ -29,7 +29,7 @@ #++ module Versions::Scopes - class OrderBySemverName + class OrderBySemverName# < Scopes::Base class << self def fetch Version.reorder Arel.sql(order_sql) diff --git a/spec/models/versions/scopes/order_by_semver_name_spec.rb b/spec/models/versions/scopes/order_by_semver_name_spec.rb index 861a07f975f..3352d255e85 100644 --- a/spec/models/versions/scopes/order_by_semver_name_spec.rb +++ b/spec/models/versions/scopes/order_by_semver_name_spec.rb @@ -2,15 +2,32 @@ require 'spec_helper' describe Versions::Scopes::OrderBySemverName, type: :model do let(:project) { FactoryBot.create(:project) } - let!(:version1) { FactoryBot.create(:version, name: "aaaaa 1.", project: project) } - let!(:version2) { FactoryBot.create(:version, name: "aaaaa", project: project) } - let!(:version3) { FactoryBot.create(:version, name: "1.10. aaa", project: project) } - let!(:version4) { FactoryBot.create(:version, name: "1.1. zzz", project: project) } - let!(:version5) { FactoryBot.create(:version, name: "1.2. mmm", project: project) } - let!(:version6) { FactoryBot.create(:version, name: "1. xxxx", project: project) } + let!(:version1) do + FactoryBot.create(:version, name: "aaaaa 1.", project: project) + end + let!(:version2) do + FactoryBot.create(:version, name: "aaaaa", project: project) + end + let!(:version3) do + FactoryBot.create(:version, name: "1.10. aaa", project: project) + end + let!(:version4) do + FactoryBot.create(:version, name: "1.1. zzz", project: project, start_date: Date.today, effective_date: Date.today + 1.day) + end + let!(:version5) do + FactoryBot.create(:version, name: "1.2. mmm", project: project, start_date: Date.today) + end + let!(:version6) do + FactoryBot.create(:version, name: "1. xxxx", project: project, start_date: Date.today + 5.days) + end it 'returns the versions in semver order' do expect(described_class.fetch.to_a) .to eql [version6, version4, version5, version3, version2, version1] end + + it 'is also callable on the version class' do + expect(Version.order_by_semver_name.to_a) + .to eql [version6, version4, version5, version3, version2, version1] + end end