Commit be090a5f authored by charlie ablett's avatar charlie ablett

Add constraint and separate out null column

parent 5927399c
......@@ -5,7 +5,7 @@ class AddIssueIndexToTestReport < ActiveRecord::Migration[6.1]
disable_ddl_transaction!
INDEX_NAME = 'index_test_reports_on_issue_id'
INDEX_NAME = 'index_requirements_management_test_reports_on_issue_id'
def up
add_concurrent_index :requirements_management_test_reports, :issue_id, name: INDEX_NAME
......
......@@ -3,23 +3,15 @@
class ChangeColumnNullTestReportRequirement < ActiveRecord::Migration[6.1]
include Gitlab::Database::MigrationHelpers
disable_ddl_transaction!
TARGET_TABLE = :requirements_management_test_reports
def up
with_lock_retries do
change_column_null :requirements_management_test_reports, :requirement_id, true
change_column_null TARGET_TABLE, :requirement_id, true
end
add_concurrent_foreign_key :requirements_management_test_reports, :issues, column: :issue_id
end
def down
with_lock_retries do
remove_foreign_key_if_exists(:requirements_management_test_reports, column: :issue_id)
end
with_lock_retries do
change_column_null :requirements_management_test_reports, :requirement_id, false
end
# no-op as it's difficult to revert
end
end
# frozen_string_literal: true
class AddRequirementTestReportsForeignKey < ActiveRecord::Migration[6.1]
include Gitlab::Database::MigrationHelpers
disable_ddl_transaction!
TARGET_TABLE = :requirements_management_test_reports
CONSTRAINT_NAME = 'requirements_test_reports_requirement_id_xor_issue_id'
def up
add_concurrent_foreign_key TARGET_TABLE, :issues, column: :issue_id
add_check_constraint(TARGET_TABLE, 'num_nonnulls(requirement_id, issue_id) = 1', CONSTRAINT_NAME)
end
def down
remove_check_constraint TARGET_TABLE, CONSTRAINT_NAME
with_lock_retries do
remove_foreign_key_if_exists(TARGET_TABLE, column: :issue_id)
end
end
end
b84505713afce3bf0673329a3a4eaf85a00d4f8948f56d43d365d6cc47ef629c
\ No newline at end of file
......@@ -17464,7 +17464,8 @@ CREATE TABLE requirements_management_test_reports (
author_id bigint,
state smallint NOT NULL,
build_id bigint,
issue_id bigint
issue_id bigint,
CONSTRAINT requirements_test_reports_requirement_id_xor_issue_id CHECK ((num_nonnulls(requirement_id, issue_id) = 1))
);
CREATE SEQUENCE requirements_management_test_reports_id_seq
......@@ -24426,6 +24427,8 @@ CREATE INDEX index_requirements_management_test_reports_on_author_id ON requirem
CREATE INDEX index_requirements_management_test_reports_on_build_id ON requirements_management_test_reports USING btree (build_id);
CREATE INDEX index_requirements_management_test_reports_on_issue_id ON requirements_management_test_reports USING btree (issue_id);
CREATE INDEX index_requirements_management_test_reports_on_requirement_id ON requirements_management_test_reports USING btree (requirement_id);
CREATE INDEX index_requirements_on_author_id ON requirements USING btree (author_id);
......@@ -24718,8 +24721,6 @@ CREATE UNIQUE INDEX index_terraform_states_on_uuid ON terraform_states USING btr
CREATE UNIQUE INDEX index_test_case_failures_unique_columns ON ci_test_case_failures USING btree (test_case_id, failed_at DESC, build_id);
CREATE INDEX index_test_reports_on_issue_id ON requirements_management_test_reports USING btree (issue_id);
CREATE INDEX index_timelogs_on_issue_id ON timelogs USING btree (issue_id);
CREATE INDEX index_timelogs_on_merge_request_id ON timelogs USING btree (merge_request_id);
......@@ -12,6 +12,7 @@ module RequirementsManagement
validates :state, presence: true
validate :only_one_requirement_association
validate :only_requirement_type_issue
enum state: { passed: 1, failed: 2 }
......@@ -69,7 +70,10 @@ module RequirementsManagement
end
def only_one_requirement_association
errors.add(:base, 'Must be associated with either a RequirementsManagement::Requirement and an Issue of type `requirement`, but not both') unless !!requirement ^ !!requirement_issue
errors.add(:base, 'Must be associated with either a RequirementsManagement::Requirement OR an Issue of type `requirement`, but not both') unless !!requirement ^ !!requirement_issue
end
def only_requirement_type_issue
errors.add(:requirement_issue, 'must be an issue of type `Requirement`') if requirement_issue && !requirement_issue.requirement?
end
end
......
......@@ -17,7 +17,7 @@ RSpec.describe RequirementsManagement::TestReport do
let(:requirement) { build(:requirement) }
let(:requirement_issue) { build(:requirement_issue) }
let(:requirement_error) { /Must be associated with either a RequirementsManagement::Requirement and an Issue of type `requirement`, but not both/ }
let(:requirement_error) { /Must be associated with either a RequirementsManagement::Requirement OR an Issue of type `requirement`, but not both/ }
it { is_expected.to validate_presence_of(:state) }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment