diff --git a/app/models/relation_transition.rb b/app/models/relation_transition.rb index a838c10..642816f 100644 --- a/app/models/relation_transition.rb +++ b/app/models/relation_transition.rb @@ -19,6 +19,8 @@ class RelationTransition < ApplicationRecord validates :name, good_small_text: true, uniqueness: true + validates :to_status, uniqueness: { scope: :from_status } + validate :statuses_are_not_equal private diff --git a/db/migrate/20190921161613_create_relation_transitions.rb b/db/migrate/20190921161613_create_relation_transitions.rb index 51bc253..aad20c9 100644 --- a/db/migrate/20190921161613_create_relation_transitions.rb +++ b/db/migrate/20190921161613_create_relation_transitions.rb @@ -7,7 +7,9 @@ class CreateRelationTransitions < ActiveRecord::Migration[6.0] create_table :relation_transitions do |t| t.timestamps null: false - t.references :from_status, foreign_key: { to_table: :relation_statuses } + t.references :from_status, + null: true, + foreign_key: { to_table: :relation_statuses } t.references :to_status, null: false, diff --git a/db/migrate/20191001211809_unique_index_statuses_on_relation_transitions.rb b/db/migrate/20191001211809_unique_index_statuses_on_relation_transitions.rb new file mode 100644 index 0000000..bec7f5b --- /dev/null +++ b/db/migrate/20191001211809_unique_index_statuses_on_relation_transitions.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +class UniqueIndexStatusesOnRelationTransitions < ActiveRecord::Migration[6.0] + def change + reversible do |dir| + dir.down do + execute <<~SQL + DROP INDEX + index_relation_transitions_on_to_status_id_when_from_status_id_is_null + SQL + end + + dir.up do + execute <<~SQL + CREATE UNIQUE INDEX + index_relation_transitions_on_to_status_id_when_from_status_id_is_null + ON relation_transitions + USING btree + (to_status_id) + WHERE from_status_id IS NULL; + SQL + end + end + end +end diff --git a/db/structure.sql b/db/structure.sql index 6fd0090..3c71984 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -1433,6 +1433,13 @@ CREATE UNIQUE INDEX index_relation_transitions_on_name ON public.relation_transi CREATE INDEX index_relation_transitions_on_to_status_id ON public.relation_transitions USING btree (to_status_id); +-- +-- Name: index_relation_transitions_on_to_status_id_when_from_status_id_; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX index_relation_transitions_on_to_status_id_when_from_status_id_ ON public.relation_transitions USING btree (to_status_id) WHERE (from_status_id IS NULL); + + -- -- Name: index_relationships_on_from_date; Type: INDEX; Schema: public; Owner: - -- @@ -1717,6 +1724,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('20190930205337'), ('20190930210852'), ('20190930215223'), -('20191001022049'); +('20191001022049'), +('20191001211809'); diff --git a/spec/models/relation_transition_spec.rb b/spec/models/relation_transition_spec.rb index 55ae2b0..07463fa 100644 --- a/spec/models/relation_transition_spec.rb +++ b/spec/models/relation_transition_spec.rb @@ -28,6 +28,13 @@ RSpec.describe RelationTransition do is_expected.to validate_presence_of(:to_status).with_message(:required) end + # Does not work with relations, but I don't want to use IDs. + # Will wait while matcher will be upgraded. + xit do + is_expected.to \ + validate_uniqueness_of(:to_status_id).scoped_to(:from_status_id) + end + it { is_expected.not_to allow_value subject.from_status } end