From c00a837105f892adcb251b7f0935a4d0b9767e06 Mon Sep 17 00:00:00 2001 From: Urban Rotnik Date: Tue, 8 Oct 2019 13:38:57 +0200 Subject: [PATCH] Add models for RepositoryStatus column type --- app/models/repository_cell.rb | 7 + app/models/repository_status_item.rb | 14 ++ app/models/repository_status_value.rb | 12 + app/models/user.rb | 20 ++ config/initializers/extends.rb | 3 +- ...03091614_create_repository_status_items.rb | 16 ++ ...7144622_create_repository_status_values.rb | 14 ++ db/structure.sql | 227 ++++++++++++++++++ spec/factories/repository_cells.rb | 7 + spec/factories/repository_columns.rb | 4 + spec/factories/repository_status_items.rb | 11 + spec/factories/repository_status_values.rb | 7 + spec/models/repository_cell_spec.rb | 5 + spec/models/repository_status_item_spec.rb | 34 +++ spec/models/repository_status_value_spec.rb | 23 ++ 15 files changed, 403 insertions(+), 1 deletion(-) create mode 100644 app/models/repository_status_item.rb create mode 100644 app/models/repository_status_value.rb create mode 100644 db/migrate/20191003091614_create_repository_status_items.rb create mode 100644 db/migrate/20191007144622_create_repository_status_values.rb create mode 100644 spec/factories/repository_status_items.rb create mode 100644 spec/factories/repository_status_values.rb create mode 100644 spec/models/repository_status_item_spec.rb create mode 100644 spec/models/repository_status_value_spec.rb diff --git a/app/models/repository_cell.rb b/app/models/repository_cell.rb index 826f61e49..20e9efec7 100644 --- a/app/models/repository_cell.rb +++ b/app/models/repository_cell.rb @@ -33,6 +33,13 @@ class RepositoryCell < ActiveRecord::Base end), optional: true, foreign_key: :value_id + belongs_to :repository_status_value, + (lambda do + includes(:repository_cell) + .where(repository_cells: { value_type: 'RepositoryStatusValue' }) + end), + optional: true, foreign_key: :value_id, inverse_of: :repository_cell + validates_inclusion_of :repository_column, in: (lambda do |cell| cell.repository_row&.repository&.repository_columns || [] diff --git a/app/models/repository_status_item.rb b/app/models/repository_status_item.rb new file mode 100644 index 000000000..735da93c5 --- /dev/null +++ b/app/models/repository_status_item.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +class RepositoryStatusItem < ApplicationRecord + validates :repository, :repository_column, :icon, presence: true + validates :status, presence: true, length: { minimum: Constants::NAME_MIN_LENGTH, + maximum: Constants::NAME_MAX_LENGTH } + belongs_to :repository + belongs_to :repository_column + belongs_to :created_by, foreign_key: 'created_by_id', class_name: 'User', optional: true, + inverse_of: :created_repositroy_status_types + belongs_to :last_modified_by, foreign_key: 'last_modified_by_id', class_name: 'User', optional: true, + inverse_of: :modified_repositroy_status_types + has_many :repository_status_values, inverse_of: :repository_status_item, dependent: :delete_all +end diff --git a/app/models/repository_status_value.rb b/app/models/repository_status_value.rb new file mode 100644 index 000000000..5a4f3ae73 --- /dev/null +++ b/app/models/repository_status_value.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +class RepositoryStatusValue < ApplicationRecord + validates :repository_status_item, presence: true + + belongs_to :repository_status_item + belongs_to :created_by, foreign_key: 'created_by_id', class_name: 'User', optional: true, + inverse_of: :created_repositroy_status_value + belongs_to :last_modified_by, foreign_key: 'last_modified_by_id', class_name: 'User', optional: true, + inverse_of: :modified_repositroy_status_value + has_one :repository_cell, as: :value, dependent: :destroy, inverse_of: :value +end diff --git a/app/models/user.rb b/app/models/user.rb index eac096ec2..3e433fd74 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -214,6 +214,26 @@ class User < ApplicationRecord has_many :assigned_my_module_repository_rows, class_name: 'MyModuleRepositoryRow', foreign_key: 'assigned_by_id' + has_many :created_repositroy_status_types, + class_name: 'RepositoryStatusItem', + foreign_key: 'created_by_id', + inverse_of: :created_by, + dependent: :nullify + has_many :modified_repositroy_status_types, + class_name: 'RepositoryStatusItem', + foreign_key: 'last_modified_by_id', + inverse_of: :last_modified_by, + dependent: :nullify + has_many :created_repositroy_status_value, + class_name: 'RepositoryStatusValue', + foreign_key: 'created_by_id', + inverse_of: :created_by, + dependent: :nullify + has_many :modified_repositroy_status_value, + class_name: 'RepositoryStatusValue', + foreign_key: 'last_modified_by_id', + inverse_of: :last_modified_by, + dependent: :nullify has_many :user_notifications, inverse_of: :user has_many :notifications, through: :user_notifications diff --git a/config/initializers/extends.rb b/config/initializers/extends.rb index 98010eeaa..2900d9cb2 100644 --- a/config/initializers/extends.rb +++ b/config/initializers/extends.rb @@ -45,7 +45,8 @@ class Extends REPOSITORY_DATA_TYPES = { RepositoryTextValue: 0, RepositoryDateValue: 1, RepositoryListValue: 2, - RepositoryAssetValue: 3 } + RepositoryAssetValue: 3, + RepositoryStatusValue: 4 } # Data types which can be imported to repository, # name should match record in REPOSITORY_DATA_TYPES diff --git a/db/migrate/20191003091614_create_repository_status_items.rb b/db/migrate/20191003091614_create_repository_status_items.rb new file mode 100644 index 000000000..4e8ef9336 --- /dev/null +++ b/db/migrate/20191003091614_create_repository_status_items.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +class CreateRepositoryStatusItems < ActiveRecord::Migration[6.0] + def change + create_table :repository_status_items do |t| + t.string :status, null: false, index: true + t.string :icon, null: false + t.references :repository, null: false, foreign_key: true + t.references :repository_column, null: false, foreign_key: true + t.references :created_by, index: true, foreign_key: { to_table: :users }, null: true + t.references :last_modified_by, index: true, foreign_key: { to_table: :users }, null: true + + t.timestamps + end + end +end diff --git a/db/migrate/20191007144622_create_repository_status_values.rb b/db/migrate/20191007144622_create_repository_status_values.rb new file mode 100644 index 000000000..4506b5fa0 --- /dev/null +++ b/db/migrate/20191007144622_create_repository_status_values.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +class CreateRepositoryStatusValues < ActiveRecord::Migration[6.0] + def change + create_table :repository_status_values do |t| + t.references :created_by, index: true, foreign_key: { to_table: :users }, null: true + t.references :last_modified_by, index: true, foreign_key: { to_table: :users }, null: true + t.references :repository_status_item, null: false, foreign_key: true, + index: { name: 'index_on_rep_status_type_id' } + + t.timestamps + end + end +end diff --git a/db/structure.sql b/db/structure.sql index f885d647b..1b960cfc6 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -9,6 +9,20 @@ SET xmloption = content; SET client_min_messages = warning; SET row_security = off; +-- +-- Name: plpgsql; Type: EXTENSION; Schema: -; Owner: - +-- + +CREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog; + + +-- +-- Name: EXTENSION plpgsql; Type: COMMENT; Schema: -; Owner: - +-- + +COMMENT ON EXTENSION plpgsql IS 'PL/pgSQL procedural language'; + + -- -- Name: btree_gist; Type: EXTENSION; Schema: -; Owner: - -- @@ -1345,6 +1359,75 @@ CREATE SEQUENCE public.repository_rows_id_seq ALTER SEQUENCE public.repository_rows_id_seq OWNED BY public.repository_rows.id; +-- +-- Name: repository_status_items; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.repository_status_items ( + id bigint NOT NULL, + status character varying NOT NULL, + icon character varying NOT NULL, + repository_id bigint NOT NULL, + repository_column_id bigint NOT NULL, + created_by_id bigint, + last_modified_by_id bigint, + created_at timestamp(6) without time zone NOT NULL, + updated_at timestamp(6) without time zone NOT NULL +); + + +-- +-- Name: repository_status_items_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.repository_status_items_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: repository_status_items_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.repository_status_items_id_seq OWNED BY public.repository_status_items.id; + + +-- +-- Name: repository_status_values; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.repository_status_values ( + id bigint NOT NULL, + created_by_id bigint, + last_modified_by_id bigint, + repository_status_item_id bigint NOT NULL, + created_at timestamp(6) without time zone NOT NULL, + updated_at timestamp(6) without time zone NOT NULL +); + + +-- +-- Name: repository_status_values_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.repository_status_values_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: repository_status_values_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.repository_status_values_id_seq OWNED BY public.repository_status_values.id; + + -- -- Name: repository_table_states; Type: TABLE; Schema: public; Owner: - -- @@ -2799,6 +2882,20 @@ ALTER TABLE ONLY public.repository_list_values ALTER COLUMN id SET DEFAULT nextv ALTER TABLE ONLY public.repository_rows ALTER COLUMN id SET DEFAULT nextval('public.repository_rows_id_seq'::regclass); +-- +-- Name: repository_status_items id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.repository_status_items ALTER COLUMN id SET DEFAULT nextval('public.repository_status_items_id_seq'::regclass); + + +-- +-- Name: repository_status_values id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.repository_status_values ALTER COLUMN id SET DEFAULT nextval('public.repository_status_values_id_seq'::regclass); + + -- -- Name: repository_table_states id; Type: DEFAULT; Schema: public; Owner: - -- @@ -3331,6 +3428,22 @@ ALTER TABLE ONLY public.repository_rows ADD CONSTRAINT repository_rows_pkey PRIMARY KEY (id); +-- +-- Name: repository_status_items repository_status_items_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.repository_status_items + ADD CONSTRAINT repository_status_items_pkey PRIMARY KEY (id); + + +-- +-- Name: repository_status_values repository_status_values_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.repository_status_values + ADD CONSTRAINT repository_status_values_pkey PRIMARY KEY (id); + + -- -- Name: repository_table_states repository_table_states_pkey; Type: CONSTRAINT; Schema: public; Owner: - -- @@ -4103,6 +4216,13 @@ CREATE UNIQUE INDEX index_oauth_access_tokens_on_token ON public.oauth_access_to CREATE UNIQUE INDEX index_oauth_applications_on_uid ON public.oauth_applications USING btree (uid); +-- +-- Name: index_on_rep_status_type_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_on_rep_status_type_id ON public.repository_status_values USING btree (repository_status_item_id); + + -- -- Name: index_projects_on_archived_by_id; Type: INDEX; Schema: public; Owner: - -- @@ -4502,6 +4622,55 @@ CREATE INDEX index_repository_rows_on_name ON public.repository_rows USING gin ( CREATE INDEX index_repository_rows_on_repository_id ON public.repository_rows USING btree (repository_id); +-- +-- Name: index_repository_status_items_on_created_by_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_repository_status_items_on_created_by_id ON public.repository_status_items USING btree (created_by_id); + + +-- +-- Name: index_repository_status_items_on_last_modified_by_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_repository_status_items_on_last_modified_by_id ON public.repository_status_items USING btree (last_modified_by_id); + + +-- +-- Name: index_repository_status_items_on_repository_column_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_repository_status_items_on_repository_column_id ON public.repository_status_items USING btree (repository_column_id); + + +-- +-- Name: index_repository_status_items_on_repository_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_repository_status_items_on_repository_id ON public.repository_status_items USING btree (repository_id); + + +-- +-- Name: index_repository_status_items_on_status; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_repository_status_items_on_status ON public.repository_status_items USING btree (status); + + +-- +-- Name: index_repository_status_values_on_created_by_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_repository_status_values_on_created_by_id ON public.repository_status_values USING btree (created_by_id); + + +-- +-- Name: index_repository_status_values_on_last_modified_by_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_repository_status_values_on_last_modified_by_id ON public.repository_status_values USING btree (last_modified_by_id); + + -- -- Name: index_repository_table_states_on_repository_id; Type: INDEX; Schema: public; Owner: - -- @@ -5216,6 +5385,14 @@ CREATE INDEX index_wopi_actions_on_extension_and_action ON public.wopi_actions U CREATE INDEX index_zip_exports_on_user_id ON public.zip_exports USING btree (user_id); +-- +-- Name: repository_status_items fk_rails_00642f1707; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.repository_status_items + ADD CONSTRAINT fk_rails_00642f1707 FOREIGN KEY (repository_id) REFERENCES public.repositories(id); + + -- -- Name: sample_custom_fields fk_rails_01916e6992; Type: FK CONSTRAINT; Schema: public; Owner: - -- @@ -5504,6 +5681,14 @@ ALTER TABLE ONLY public.experiments ADD CONSTRAINT fk_rails_4a63cb023e FOREIGN KEY (archived_by_id) REFERENCES public.users(id); +-- +-- Name: repository_status_values fk_rails_4cf67f9f1e; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.repository_status_values + ADD CONSTRAINT fk_rails_4cf67f9f1e FOREIGN KEY (last_modified_by_id) REFERENCES public.users(id); + + -- -- Name: experiments fk_rails_4d671c16af; Type: FK CONSTRAINT; Schema: public; Owner: - -- @@ -5648,6 +5833,14 @@ ALTER TABLE ONLY public.wopi_actions ADD CONSTRAINT fk_rails_736b4e5a7d FOREIGN KEY (wopi_app_id) REFERENCES public.wopi_apps(id); +-- +-- Name: repository_status_items fk_rails_74e5e4cacc; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.repository_status_items + ADD CONSTRAINT fk_rails_74e5e4cacc FOREIGN KEY (repository_column_id) REFERENCES public.repository_columns(id); + + -- -- Name: results fk_rails_79fcaa8e37; Type: FK CONSTRAINT; Schema: public; Owner: - -- @@ -5672,6 +5865,14 @@ ALTER TABLE ONLY public.checklist_items ADD CONSTRAINT fk_rails_7b68a8f1d8 FOREIGN KEY (created_by_id) REFERENCES public.users(id); +-- +-- Name: repository_status_items fk_rails_7bc42f7363; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.repository_status_items + ADD CONSTRAINT fk_rails_7bc42f7363 FOREIGN KEY (last_modified_by_id) REFERENCES public.users(id); + + -- -- Name: activities fk_rails_7e11bb717f; Type: FK CONSTRAINT; Schema: public; Owner: - -- @@ -5848,6 +6049,14 @@ ALTER TABLE ONLY public.reports ADD CONSTRAINT fk_rails_9a0a9c9bec FOREIGN KEY (project_id) REFERENCES public.projects(id); +-- +-- Name: repository_status_items fk_rails_9acc03f846; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.repository_status_items + ADD CONSTRAINT fk_rails_9acc03f846 FOREIGN KEY (created_by_id) REFERENCES public.users(id); + + -- -- Name: results fk_rails_9be849c454; Type: FK CONSTRAINT; Schema: public; Owner: - -- @@ -5856,6 +6065,14 @@ ALTER TABLE ONLY public.results ADD CONSTRAINT fk_rails_9be849c454 FOREIGN KEY (archived_by_id) REFERENCES public.users(id); +-- +-- Name: repository_status_values fk_rails_9d357798c5; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.repository_status_values + ADD CONSTRAINT fk_rails_9d357798c5 FOREIGN KEY (created_by_id) REFERENCES public.users(id); + + -- -- Name: step_tables fk_rails_9e0e7dea0d; Type: FK CONSTRAINT; Schema: public; Owner: - -- @@ -5912,6 +6129,14 @@ ALTER TABLE ONLY public.custom_fields ADD CONSTRAINT fk_rails_a25c0b1d1a FOREIGN KEY (user_id) REFERENCES public.users(id); +-- +-- Name: repository_status_values fk_rails_a3a2aede5b; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.repository_status_values + ADD CONSTRAINT fk_rails_a3a2aede5b FOREIGN KEY (repository_status_item_id) REFERENCES public.repository_status_items(id); + + -- -- Name: result_assets fk_rails_a418904d39; Type: FK CONSTRAINT; Schema: public; Owner: - -- @@ -6522,6 +6747,8 @@ INSERT INTO "schema_migrations" (version) VALUES ('20190903145834'), ('20190910125740'), ('20191001133557'), +('20191003091614'), +('20191007144622'), ('20191009146101'); diff --git a/spec/factories/repository_cells.rb b/spec/factories/repository_cells.rb index e06597088..d05cd46d2 100644 --- a/spec/factories/repository_cells.rb +++ b/spec/factories/repository_cells.rb @@ -31,5 +31,12 @@ FactoryBot.define do repository_cell.value ||= build(:repository_asset_value, repository_cell: repository_cell) end end + + trait :status_value do + repository_column { create :repository_column, :status_type, repository: repository_row.repository } + after(:build) do |repository_cell| + repository_cell.value ||= build(:repository_status_value, repository_cell: repository_cell) + end + end end end diff --git a/spec/factories/repository_columns.rb b/spec/factories/repository_columns.rb index 7c47ed993..15aed5426 100644 --- a/spec/factories/repository_columns.rb +++ b/spec/factories/repository_columns.rb @@ -22,5 +22,9 @@ FactoryBot.define do trait :asset_type do data_type { :RepositoryAssetValue } end + + trait :status_type do + data_type { :RepositoryStatusValue } + end end end diff --git a/spec/factories/repository_status_items.rb b/spec/factories/repository_status_items.rb new file mode 100644 index 000000000..11e357853 --- /dev/null +++ b/spec/factories/repository_status_items.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :repository_status_item do + sequence(:icon) { |n| "icon-#{n}" } + sequence(:status) { |n| "status-#{n}" } + repository + repository_column + created_by { create :user } + end +end diff --git a/spec/factories/repository_status_values.rb b/spec/factories/repository_status_values.rb new file mode 100644 index 000000000..7425b3b63 --- /dev/null +++ b/spec/factories/repository_status_values.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :repository_status_value do + repository_status_item + end +end diff --git a/spec/models/repository_cell_spec.rb b/spec/models/repository_cell_spec.rb index 1c4f1f495..973a8f646 100644 --- a/spec/models/repository_cell_spec.rb +++ b/spec/models/repository_cell_spec.rb @@ -8,6 +8,7 @@ describe RepositoryCell, type: :model do let(:repository_cell_d) { build :repository_cell, :date_value } let(:repository_cell_l) { build :repository_cell, :list_value } let(:repository_cell_a) { build :repository_cell, :asset_value } + let(:repository_cell_s) { build :repository_cell, :status_value } context 'when do not have value' do it 'is not valid' do @@ -31,6 +32,10 @@ describe RepositoryCell, type: :model do it 'is valid for asset value' do expect(repository_cell_a).to be_valid end + + it 'is valid for asset value' do + expect(repository_cell_s).to be_valid + end end it 'should be of class RepositoryCell' do diff --git a/spec/models/repository_status_item_spec.rb b/spec/models/repository_status_item_spec.rb new file mode 100644 index 000000000..b6a892bbf --- /dev/null +++ b/spec/models/repository_status_item_spec.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe RepositoryStatusItem do + let(:repository_status_item) { build :repository_status_item } + + it 'is valid' do + expect(repository_status_item).to be_valid + end + + describe 'Validations' do + describe '#repository' do + it { is_expected.to validate_presence_of(:repository) } + end + + describe '#icon' do + it { is_expected.to validate_presence_of(:icon) } + end + + describe '#status' do + it { is_expected.to validate_presence_of(:status) } + it { is_expected.to validate_length_of(:status).is_at_most(255) } + end + end + + describe 'Associations' do + it { is_expected.to belong_to(:repository) } + it { is_expected.to belong_to(:repository_column) } + it { is_expected.to belong_to(:created_by).optional } + it { is_expected.to belong_to(:last_modified_by).optional } + it { is_expected.to have_many(:repository_status_values) } + end +end diff --git a/spec/models/repository_status_value_spec.rb b/spec/models/repository_status_value_spec.rb new file mode 100644 index 000000000..43d316195 --- /dev/null +++ b/spec/models/repository_status_value_spec.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe RepositoryStatusValue do + let(:repository_status_value) { build :repository_status_value } + + it 'is valid' do + expect(repository_status_value).to be_valid + end + + describe 'Validations' do + describe '#repository_status_item' do + it { is_expected.to validate_presence_of(:repository_status_item) } + end + end + + describe 'Associations' do + it { is_expected.to belong_to(:repository_status_item) } + it { is_expected.to belong_to(:created_by).optional } + it { is_expected.to belong_to(:last_modified_by).optional } + end +end