diff --git a/app/admin/lab_record_imports.rb b/app/admin/lab_record_imports.rb index 7bda874..dd39c57 100644 --- a/app/admin/lab_record_imports.rb +++ b/app/admin/lab_record_imports.rb @@ -1,5 +1,6 @@ ActiveAdmin.register LabRecordImport do - actions :index, :show + actions :index, :edit, :update + permit_params :tags, tag_ids: [] includes :site @@ -17,8 +18,12 @@ column :header_row column :data_rows_from column :data_rows_to + column :tags column :error_message column :uploaded_at + if Tag.count > 0 && current_admin_user.admin? + actions + end end filter :site @@ -27,4 +32,12 @@ filter :error_message filter :created_at filter :uploaded_at + + form title: 'Tags', :html => {:class => "tags_list"} do |f| + f.input :tags, as: :select, collection: Tag.all, multiple: true, label: false + f.actions do + f.action :submit, as: :button, label: 'Update Tags' + f.action :cancel, :wrapper_html => { :class => 'cancel'}, label: 'Cancel' + end + end end diff --git a/app/admin/tags.rb b/app/admin/tags.rb new file mode 100644 index 0000000..39643d5 --- /dev/null +++ b/app/admin/tags.rb @@ -0,0 +1,26 @@ +ActiveAdmin.register Tag do + permit_params :name + + index do + id_column + column :name + column :created_at + actions + end + + filter :id + filter :name + filter :created_at + + controller do + def destroy + tag = Tag.find(params[:id]) + if tag.destroy + flash[:notice] = "Tag '#{tag.name}' successfully deleted" + else + flash[:error] = "Couldn't delete tag '#{tag.name}'. Is it currently being used by any Lab Record Import?" + end + redirect_to action: :index + end + end +end diff --git a/app/assets/stylesheets/active_admin.scss b/app/assets/stylesheets/active_admin.scss index 34d500c..19eefa1 100644 --- a/app/assets/stylesheets/active_admin.scss +++ b/app/assets/stylesheets/active_admin.scss @@ -23,3 +23,7 @@ form#edit_site fieldset > ol > li.boolean label { padding-left: 0; } + +.tags_list li { + list-style: none; +} diff --git a/app/models/lab_record_import.rb b/app/models/lab_record_import.rb index b7c0a75..614391c 100644 --- a/app/models/lab_record_import.rb +++ b/app/models/lab_record_import.rb @@ -3,6 +3,8 @@ class LabRecordImport < ApplicationRecord has_one_attached :sheet_file has_one_attached :rows_file has_many :lab_records, dependent: :destroy + has_many :lab_record_imports_tags, dependent: :destroy + has_many :tags, through: :lab_record_imports_tags # accepts_nested_attributes_for :lab_records diff --git a/app/models/lab_record_imports_tag.rb b/app/models/lab_record_imports_tag.rb new file mode 100644 index 0000000..18c009b --- /dev/null +++ b/app/models/lab_record_imports_tag.rb @@ -0,0 +1,6 @@ +class LabRecordImportsTag < ApplicationRecord + belongs_to :lab_record_import + belongs_to :tag + + validates :tag_id, uniqueness: { scope: [:lab_record_import_id] } +end diff --git a/app/models/tag.rb b/app/models/tag.rb new file mode 100644 index 0000000..3bc8343 --- /dev/null +++ b/app/models/tag.rb @@ -0,0 +1,5 @@ +class Tag < ApplicationRecord + validates :name, presence: true, uniqueness: true + has_many :lab_record_imports_tags, dependent: :restrict_with_error + has_many :lab_record_imports, through: :lab_record_imports_tags +end diff --git a/config/locales/en.yml b/config/locales/en.yml index decc5a8..1ede96a 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -31,3 +31,7 @@ en: hello: "Hello world" + active_admin: + resources: + lab_record_import: + edit: "Edit tags" diff --git a/db/migrate/20201117221635_create_tags.rb b/db/migrate/20201117221635_create_tags.rb new file mode 100644 index 0000000..0d2e749 --- /dev/null +++ b/db/migrate/20201117221635_create_tags.rb @@ -0,0 +1,10 @@ +class CreateTags < ActiveRecord::Migration[5.2] + def change + create_table :tags do |t| + t.string :name, :null => false + t.timestamps + + t.index [:name], unique: true + end + end +end diff --git a/db/migrate/20201117224218_create_lab_record_imports_tags.rb b/db/migrate/20201117224218_create_lab_record_imports_tags.rb new file mode 100644 index 0000000..87c7b16 --- /dev/null +++ b/db/migrate/20201117224218_create_lab_record_imports_tags.rb @@ -0,0 +1,11 @@ +class CreateLabRecordImportsTags < ActiveRecord::Migration[5.2] + def change + create_table :lab_record_imports_tags do |t| + t.references :lab_record_import, foreign_key: true, :null => false + t.references :tag, foreign_key: true, :null => false + t.timestamps + + t.index [ :lab_record_import_id, :tag_id ], :unique => true, :name => 'index_on_lab_record_import_id_and_tag_id' + end + end +end diff --git a/db/schema.rb b/db/schema.rb index d9549b6..be1297f 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2020_04_20_153254) do +ActiveRecord::Schema.define(version: 2020_11_17_224218) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -128,6 +128,16 @@ t.index ["site_id"], name: "index_lab_record_imports_on_site_id" end + create_table "lab_record_imports_tags", force: :cascade do |t| + t.bigint "lab_record_import_id", null: false + t.bigint "tag_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["lab_record_import_id", "tag_id"], name: "index_on_lab_record_import_id_and_tag_id", unique: true + t.index ["lab_record_import_id"], name: "index_lab_record_imports_tags_on_lab_record_import_id" + t.index ["tag_id"], name: "index_lab_record_imports_tags_on_tag_id" + end + create_table "lab_records", force: :cascade do |t| t.bigint "lab_record_import_id" t.bigint "site_id" @@ -269,6 +279,13 @@ t.datetime "updated_at", null: false end + create_table "tags", force: :cascade do |t| + t.string "name", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["name"], name: "index_tags_on_name", unique: true + end + create_table "users", force: :cascade do |t| t.string "provider", default: "email", null: false t.string "uid", default: "", null: false @@ -293,6 +310,8 @@ add_foreign_key "antibiotic_consumption_stats", "sites" add_foreign_key "electronic_pharmacy_stock_records", "sites" add_foreign_key "lab_record_imports", "sites" + add_foreign_key "lab_record_imports_tags", "lab_record_imports" + add_foreign_key "lab_record_imports_tags", "tags" add_foreign_key "lab_records", "lab_record_imports" add_foreign_key "lab_records", "sites" add_foreign_key "patient_entries", "patient_locations" diff --git a/spec/factories/lab_record_imports_tags.rb b/spec/factories/lab_record_imports_tags.rb new file mode 100644 index 0000000..ef64ee4 --- /dev/null +++ b/spec/factories/lab_record_imports_tags.rb @@ -0,0 +1,4 @@ +FactoryBot.define do + factory :lab_record_imports_tag do + end +end diff --git a/spec/factories/tags.rb b/spec/factories/tags.rb new file mode 100644 index 0000000..b3bffbf --- /dev/null +++ b/spec/factories/tags.rb @@ -0,0 +1,5 @@ +FactoryBot.define do + factory :tag do + name { FFaker::Tweet.tags } + end +end diff --git a/spec/models/lab_record_import_spec.rb b/spec/models/lab_record_import_spec.rb index 79ffff2..efd763b 100644 --- a/spec/models/lab_record_import_spec.rb +++ b/spec/models/lab_record_import_spec.rb @@ -16,4 +16,7 @@ it 'obfuscates if both `patient_or_lab_record_id` and `phi` are non-empty' do expect(create(:lab_record_import).skip_obfuscation?).to eq(false) end + + it { is_expected.to have_many(:tags).through(:lab_record_imports_tags) } + it { is_expected.to have_many(:lab_record_imports_tags).dependent(:destroy) } end diff --git a/spec/models/lab_record_imports_tag_spec.rb b/spec/models/lab_record_imports_tag_spec.rb new file mode 100644 index 0000000..327119b --- /dev/null +++ b/spec/models/lab_record_imports_tag_spec.rb @@ -0,0 +1,11 @@ +require 'rails_helper' + +RSpec.describe LabRecordImportsTag, type: :model do + subject do + l = create(:lab_record_import) + t = create(:tag) + build(:lab_record_imports_tag, lab_record_import_id: l.id, tag_id: t.id) + end + + it { is_expected.to validate_uniqueness_of(:tag_id).scoped_to(:lab_record_import_id) } +end diff --git a/spec/models/tag_spec.rb b/spec/models/tag_spec.rb new file mode 100644 index 0000000..478807f --- /dev/null +++ b/spec/models/tag_spec.rb @@ -0,0 +1,11 @@ +require 'rails_helper' + +RSpec.describe Tag, type: :model do + subject { build :tag } + + it { is_expected.to be_valid } + it { is_expected.to validate_presence_of(:name) } + it { is_expected.to validate_uniqueness_of(:name) } + it { is_expected.to have_many(:lab_record_imports).through(:lab_record_imports_tags) } + it { is_expected.to have_many(:lab_record_imports_tags).dependent(:restrict_with_error) } +end