Skip to content

Commit

Permalink
Make sure InstitutionSubjects can be identifier by subject+description
Browse files Browse the repository at this point in the history
* Make the Subject label unique
* Make the InstitutionSubject [institution, subject, description] unique: it means that in an Institution, the same subject can only be selected several times if the description is different (and present.)

refs #1253
  • Loading branch information
n-b committed Oct 6, 2020
1 parent 46d006f commit f8ca38e
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 1 deletion.
22 changes: 22 additions & 0 deletions app/models/institution_subject.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#
# index_institutions_subjects_on_institution_id (institution_id)
# index_institutions_subjects_on_subject_id (subject_id)
# unique_institution_subject_in_institution (subject_id,institution_id,description) UNIQUE
#
# Foreign Keys
#
Expand All @@ -36,6 +37,18 @@ class InstitutionSubject < ApplicationRecord
has_many :experts, through: :experts_subjects, inverse_of: :institutions_subjects
has_many :not_deleted_experts, through: :experts_subjects, inverse_of: :institutions_subjects

# :institution
# Other InstitutionSubjects of the same Institution, and the same Subject.
has_many :similar_institutions_subjects, -> (is) { where(subject: is.subject).where.not(id: is.id) },
through: :institution, source: :institutions_subjects, inverse_of: :similar_institutions_subjects

# Validations
#
# In an Institution, the same subject can only be selected several times`
# if the description is different (and present.)
validates :subject, uniqueness: { scope: [:institution_id, :description] }
validate :validate_description_presence

## Scopes
#
scope :support_subjects, -> do
Expand All @@ -53,6 +66,15 @@ def to_s
description
end

## Name / Description uniqueness
#
def validate_description_presence
# description mustn't be blank if there’s a similar subject
if description.blank? && similar_institutions_subjects.present?
errors.add(:description, :blank)
end
end

## used for serialization in advisors csv
#
def csv_identifier
Expand Down
2 changes: 2 additions & 0 deletions app/models/subject.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
# Indexes
#
# index_subjects_on_archived_at (archived_at)
# index_subjects_on_label (label) UNIQUE
# index_subjects_on_slug (slug) UNIQUE
# index_subjects_on_theme_id (theme_id)
#
Expand All @@ -38,6 +39,7 @@ class Subject < ApplicationRecord
## Validations
#
validates :theme, :slug, presence: true
validates :label, presence: true, uniqueness: true
before_validation :compute_slug
before_save :set_support

Expand Down
6 changes: 6 additions & 0 deletions db/migrate/20201002163301_make_subject_label_unique.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class MakeSubjectLabelUnique < ActiveRecord::Migration[6.0]
def change
add_index :subjects, :label, unique: true
add_index :institutions_subjects, [:subject_id, :institution_id, :description], unique: true, name: 'unique_institution_subject_in_institution'
end
end
4 changes: 3 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 2020_10_02_071333) do
ActiveRecord::Schema.define(version: 2020_10_02_163301) do

# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
Expand Down Expand Up @@ -243,6 +243,7 @@
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["institution_id"], name: "index_institutions_subjects_on_institution_id"
t.index ["subject_id", "institution_id", "description"], name: "unique_institution_subject_in_institution", unique: true
t.index ["subject_id"], name: "index_institutions_subjects_on_subject_id"
end

Expand Down Expand Up @@ -370,6 +371,7 @@
t.boolean "is_support", default: false
t.string "slug", null: false
t.index ["archived_at"], name: "index_subjects_on_archived_at"
t.index ["label"], name: "index_subjects_on_label", unique: true
t.index ["slug"], name: "index_subjects_on_slug", unique: true
t.index ["theme_id"], name: "index_subjects_on_theme_id"
end
Expand Down
Binary file modified doc/domain_model.pdf
Binary file not shown.
39 changes: 39 additions & 0 deletions spec/models/institution_subject_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,45 @@
is_expected.to belong_to :subject
is_expected.to belong_to :institution
end

describe 'description uniqueness in an institution' do
let(:institution) { create :institution }
let(:the_subject) { create :subject }

before do
create :institution_subject, institution: institution, subject: the_subject, description: 'FOO'
end

context 'same institution and subject and description' do
subject { build :institution_subject, institution: institution, subject: the_subject, description: 'FOO' }

it { is_expected.not_to be_valid }
end

context 'same institution and subject, no description' do
subject { build :institution_subject, institution: institution, subject: the_subject, description: '' }

it { is_expected.not_to be_valid }
end

context 'same institution and subject, differetn description' do
subject { build :institution_subject, institution: institution, subject: the_subject, description: 'BAR' }

it { is_expected.to be_valid }
end

context 'same institution, other subject' do
subject { build :institution_subject, institution: institution }

it { is_expected.to be_valid }
end

context 'other institution, same subject' do
subject { build :institution_subject, subject: the_subject }

it { is_expected.to be_valid }
end
end
end

describe 'csv_identifier' do
Expand Down

0 comments on commit f8ca38e

Please sign in to comment.