diff --git a/app/models/repository.rb b/app/models/repository.rb index d23a5d74e..fce0a148d 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -11,6 +11,7 @@ class Repository < ApplicationRecord has_many :repository_table_states, inverse_of: :repository, dependent: :destroy has_many :report_elements, inverse_of: :repository, dependent: :destroy + has_many :repository_list_items, inverse_of: :repository, dependent: :destroy auto_strip_attributes :name, nullify: false validates :name, diff --git a/app/models/repository_list_item.rb b/app/models/repository_list_item.rb index ef6837957..597aa10e9 100644 --- a/app/models/repository_list_item.rb +++ b/app/models/repository_list_item.rb @@ -1,6 +1,15 @@ class RepositoryListItem < ApplicationRecord - belongs_to :repository_list_value + has_many :repository_list_values, + foreign_key: 'selected_item_id' + belongs_to :repository, inverse_of: :repository_list_items + belongs_to :created_by, + foreign_key: :created_by_id, + class_name: 'User' + belongs_to :last_modified_by, + foreign_key: :last_modified_by_id, + class_name: 'User' validates :name, presence: true, + uniqueness: { scope: :repository, case_sensitive: false }, length: { maximum: Constants::TEXT_MAX_LENGTH } end diff --git a/app/models/repository_list_value.rb b/app/models/repository_list_value.rb index f21cd928b..3ffb1d78a 100644 --- a/app/models/repository_list_value.rb +++ b/app/models/repository_list_value.rb @@ -1,21 +1,21 @@ class RepositoryListValue < ApplicationRecord - has_many :repository_list_items, dependent: :destroy + belongs_to :selected_item, + foreign_key: :selected_item_id, + class_name: 'RepositoryListItem', + optional: true belongs_to :created_by, foreign_key: :created_by_id, - class_name: 'User', - optional: true + class_name: 'User' belongs_to :last_modified_by, foreign_key: :last_modified_by_id, - class_name: 'User', - optional: true + class_name: 'User' has_one :repository_cell, as: :value, dependent: :destroy, inverse_of: :value accepts_nested_attributes_for :repository_cell validates :repository_cell, presence: true def formatted - item = repository_list_items.find_by_id(selected_item) - return '' unless item - item.name + return '' unless selected_item + selected_item.name end end diff --git a/db/migrate/20180207095200_create_repository_list_values.rb b/db/migrate/20180207095200_create_repository_list_values.rb index e904dd1a5..e752118f1 100644 --- a/db/migrate/20180207095200_create_repository_list_values.rb +++ b/db/migrate/20180207095200_create_repository_list_values.rb @@ -1,7 +1,8 @@ class CreateRepositoryListValues < ActiveRecord::Migration[5.1] def change - create_table :repository_list_values do |t| - t.bigint :selected_item + create_table :repository_list_items do |t| + t.references :repository, foreign_key: true + t.text :name, index: true, using: :gin, null: false t.references :created_by, index: true, foreign_key: { to_table: :users } @@ -11,9 +12,16 @@ class CreateRepositoryListValues < ActiveRecord::Migration[5.1] t.timestamps end - create_table :repository_list_items do |t| - t.references :repository_list_value, foreign_key: true - t.text :name, index: true, using: :gin, null: false + create_table :repository_list_values do |t| + t.references :selected_item, + index: true, + foreign_key: { to_table: :repository_list_items } + t.references :created_by, + index: true, + foreign_key: { to_table: :users } + t.references :last_modified_by, + index: true, + foreign_key: { to_table: :users } t.timestamps end end diff --git a/db/schema.rb b/db/schema.rb index 70bbcf2f4..d87e358a0 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -395,22 +395,27 @@ ActiveRecord::Schema.define(version: 20180207095200) do end create_table "repository_list_items", force: :cascade do |t| - t.bigint "repository_list_value_id" + t.bigint "repository_id" t.text "name", null: false + t.bigint "created_by_id" + t.bigint "last_modified_by_id" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.index ["created_by_id"], name: "index_repository_list_items_on_created_by_id" + t.index ["last_modified_by_id"], name: "index_repository_list_items_on_last_modified_by_id" t.index ["name"], name: "index_repository_list_items_on_name" - t.index ["repository_list_value_id"], name: "index_repository_list_items_on_repository_list_value_id" + t.index ["repository_id"], name: "index_repository_list_items_on_repository_id" end create_table "repository_list_values", force: :cascade do |t| - t.bigint "selected_item" + t.bigint "selected_item_id" t.bigint "created_by_id" t.bigint "last_modified_by_id" t.datetime "created_at", null: false t.datetime "updated_at", null: false t.index ["created_by_id"], name: "index_repository_list_values_on_created_by_id" t.index ["last_modified_by_id"], name: "index_repository_list_values_on_last_modified_by_id" + t.index ["selected_item_id"], name: "index_repository_list_values_on_selected_item_id" end create_table "repository_rows", id: :serial, force: :cascade do |t| @@ -873,7 +878,10 @@ ActiveRecord::Schema.define(version: 20180207095200) do add_foreign_key "repository_columns", "users", column: "created_by_id" add_foreign_key "repository_date_values", "users", column: "created_by_id" add_foreign_key "repository_date_values", "users", column: "last_modified_by_id" - add_foreign_key "repository_list_items", "repository_list_values" + add_foreign_key "repository_list_items", "repositories" + add_foreign_key "repository_list_items", "users", column: "created_by_id" + add_foreign_key "repository_list_items", "users", column: "last_modified_by_id" + add_foreign_key "repository_list_values", "repository_list_items", column: "selected_item_id" add_foreign_key "repository_list_values", "users", column: "created_by_id" add_foreign_key "repository_list_values", "users", column: "last_modified_by_id" add_foreign_key "repository_rows", "users", column: "created_by_id" diff --git a/spec/factories/repository_list_items.rb b/spec/factories/repository_list_items.rb index 7fe4b1e74..416a521a2 100644 --- a/spec/factories/repository_list_items.rb +++ b/spec/factories/repository_list_items.rb @@ -1,6 +1,8 @@ FactoryBot.define do factory :repository_list_item do - repository_list_value nil name '' + repository { Repository.first || create(:repository) } + created_by { User.first || association(:project_user) } + last_modified_by { User.first || association(:project_user) } end end diff --git a/spec/models/repository_list_item_spec.rb b/spec/models/repository_list_item_spec.rb index cf6807a47..037de7710 100644 --- a/spec/models/repository_list_item_spec.rb +++ b/spec/models/repository_list_item_spec.rb @@ -7,11 +7,12 @@ RSpec.describe RepositoryListItem, type: :model do describe 'Database table' do it { should have_db_column :name } - it { should have_db_column :repository_list_value_id } + it { should have_db_column :repository_id } end describe 'Relations' do - it { should belong_to(:repository_list_value) } + it { should have_many(:repository_list_values) } + it { should belong_to(:repository) } end describe 'Validations' do @@ -19,5 +20,31 @@ RSpec.describe RepositoryListItem, type: :model do it do should validate_length_of(:name).is_at_most(Constants::TEXT_MAX_LENGTH) end + + context 'has a uniq name scoped on repository' do + let!(:user) { create :user } + let!(:repository_one) { create :repository } + let!(:repository_two) { create :repository, name: 'New repo' } + let!(:repository_list_item) do + create :repository_list_item, name: 'Test', repository: repository_one + end + + it 'creates a repository list item in same repository' do + new_item = build :repository_list_item, + name: 'Test', + repository: repository_one + expect(new_item).to_not be_valid + expect( + new_item.errors.full_messages.first + ).to eq 'Name has already been taken' + end + + it 'create a repository list item in other repository' do + new_item = build :repository_list_item, + name: 'Test', + repository: repository_two + expect(new_item).to be_valid + end + end end end diff --git a/spec/models/repository_list_value_spec.rb b/spec/models/repository_list_value_spec.rb index da1031781..2aac4dbd9 100644 --- a/spec/models/repository_list_value_spec.rb +++ b/spec/models/repository_list_value_spec.rb @@ -8,17 +8,18 @@ RSpec.describe RepositoryListValue, type: :model do describe 'Database table' do it { should have_db_column :created_by_id } it { should have_db_column :last_modified_by_id } - it { should have_db_column :selected_item } + it { should have_db_column :selected_item_id } end describe 'Relations' do it { should belong_to(:created_by).class_name('User') } it { should belong_to(:last_modified_by).class_name('User') } - it { should have_many :repository_list_items } + it { should belong_to(:selected_item).class_name('RepositoryListItem') } it { should accept_nested_attributes_for(:repository_cell) } end describe '#data' do + let!(:repository) { create :repository } let!(:repository_column) do create :repository_column, data_type: :RepositoryListValue end @@ -32,9 +33,10 @@ RSpec.describe RepositoryListValue, type: :model do it 'returns the name of a selected item' do list_item = create :repository_list_item, - repository_list_value: repository_list_value, - name: 'my item' - repository_list_value.update_attribute(:selected_item, list_item.id) + name: 'my item', + repository: repository + repository_list_value.selected_item = list_item + repository_list_value.save expect(repository_list_value.reload.formatted).to eq 'my item' end @@ -46,22 +48,22 @@ RSpec.describe RepositoryListValue, type: :model do repository_row: repository_row_two } list_item = create :repository_list_item, - repository_list_value: repository_list_value_two, - name: 'new item' - repository_list_value.update_attribute(:selected_item, list_item.id) + name: 'new item', + repository: repository + repository_list_value.selected_item = list_item expect(repository_list_value.reload.formatted).to_not eq 'my item' expect(repository_list_value.formatted).to eq '' end it 'returns an empty string if no item selected' do list_item = create :repository_list_item, - repository_list_value: repository_list_value, - name: 'my item' + name: 'my item', + repository: repository expect(repository_list_value.reload.formatted).to eq '' end it 'returns an empty string if item does not exists' do - repository_list_value.update_attribute(:selected_item, 9999999999) + repository_list_value.selected_item = nil expect(repository_list_value.reload.formatted).to eq '' end end diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb index 6a927f715..7c1063ee1 100644 --- a/spec/models/repository_spec.rb +++ b/spec/models/repository_spec.rb @@ -19,6 +19,7 @@ describe Repository, type: :model do it { should have_many :repository_rows } it { should have_many :repository_table_states } it { should have_many :report_elements } + it { should have_many(:repository_list_items).dependent(:destroy) } end describe 'Should be a valid object' do