diff --git a/app/controllers/assets_controller.rb b/app/controllers/assets_controller.rb index 99223c4b9..a3b4a04ab 100644 --- a/app/controllers/assets_controller.rb +++ b/app/controllers/assets_controller.rb @@ -103,13 +103,17 @@ class AssetsController < ApplicationController step_assoc = @asset.step result_assoc = @asset.result + repository_cell_assoc = @asset.repository_cell @assoc = step_assoc unless step_assoc.nil? @assoc = result_assoc unless result_assoc.nil? + @assoc = repository_cell_assoc unless repository_cell_assoc.nil? if @assoc.class == Step @protocol = @asset.step.protocol - else + elsif @assoc.class == Result @my_module = @assoc.my_module + else + # TBD end end @@ -121,6 +125,8 @@ class AssetsController < ApplicationController unless can_view_or_download_result_assets(@my_module) render_403 and return end + elsif @assoc.class == RepositoryCell + # TBD end end @@ -132,6 +138,8 @@ class AssetsController < ApplicationController unless can_edit_result_asset_in_module(@my_module) render_403 and return end + elsif @assoc.class == RepositoryCell + # TBD end end diff --git a/app/models/asset.rb b/app/models/asset.rb index 8ed857cf5..4badb254b 100644 --- a/app/models/asset.rb +++ b/app/models/asset.rb @@ -44,7 +44,7 @@ class Asset < ApplicationRecord # Asset validation # This could cause some problems if you create empty asset and want to # assign it to result - validate :step_or_result + validate :step_or_result_or_repository_cell belongs_to :created_by, foreign_key: 'created_by_id', @@ -55,16 +55,12 @@ class Asset < ApplicationRecord class_name: 'User', optional: true belongs_to :team, optional: true - has_one :step_asset, - inverse_of: :asset, - dependent: :destroy - has_one :step, through: :step_asset, - dependent: :nullify - - has_one :result_asset, - inverse_of: :asset, - dependent: :destroy - has_one :result, through: :result_asset, + has_one :step_asset, inverse_of: :asset, dependent: :destroy + has_one :step, through: :step_asset, dependent: :nullify + has_one :result_asset, inverse_of: :asset, dependent: :destroy + has_one :result, through: :result_asset, dependent: :nullify + has_one :repository_asset_value, inverse_of: :asset, dependent: :destroy + has_one :repository_cell, through: :repository_asset_value, dependent: :nullify has_many :report_elements, inverse_of: :asset, dependent: :destroy has_one :asset_text_datum, inverse_of: :asset, dependent: :destroy @@ -500,11 +496,13 @@ class Asset < ApplicationRecord ) end - def step_or_result + def step_or_result_or_repository_cell # We must allow both step and result to be blank because of GUI # (even though it's not really a "valid" asset) - if step.present? && result.present? - errors.add(:base, "Asset can only be result or step, not both.") + if step.present? && result.present? || + step.present? && repository_cell.present? || + result.present? && repository_cell.present? + errors.add(:base, "Asset can only be result or step or repository cell, not ever.") end end diff --git a/app/models/repository_asset_value.rb b/app/models/repository_asset_value.rb new file mode 100644 index 000000000..2d4e8dd01 --- /dev/null +++ b/app/models/repository_asset_value.rb @@ -0,0 +1,21 @@ +class RepositoryAssetValue < ApplicationRecord + belongs_to :created_by, + foreign_key: :created_by_id, + class_name: 'User', + optional: true + belongs_to :last_modified_by, + foreign_key: :last_modified_by_id, + class_name: 'User', + optional: true + belongs_to :asset, + inverse_of: :repository_asset_value, + dependent: :destroy + has_one :repository_cell, as: :value, dependent: :destroy, inverse_of: :value + accepts_nested_attributes_for :repository_cell + + validates :asset, :repository_cell, presence: true + + def formatted + asset.file + end +end diff --git a/app/models/repository_cell.rb b/app/models/repository_cell.rb index 4da8e6fc7..19474bc56 100644 --- a/app/models/repository_cell.rb +++ b/app/models/repository_cell.rb @@ -17,6 +17,11 @@ class RepositoryCell < ActiveRecord::Base where(repository_cells: { value_type: 'RepositoryListValue' }) end), optional: true, foreign_key: :value_id + belongs_to :repository_asset_value, + (lambda do + where(repository_cells: { value_type: 'RepositoryAssetValue' }) + end), + optional: true, foreign_key: :value_id validates :repository_column, presence: true validate :repository_column_data_type diff --git a/config/initializers/extends.rb b/config/initializers/extends.rb index 44c6d3781..fd6975eaf 100644 --- a/config/initializers/extends.rb +++ b/config/initializers/extends.rb @@ -42,7 +42,8 @@ class Extends # Data type name should match corresponding model's name REPOSITORY_DATA_TYPES = { RepositoryTextValue: 0, RepositoryDateValue: 1, - RepositoryListValue: 2 } + RepositoryListValue: 2, + RepositoryAssetValue: 3 } # Extra attributes used for search in repositories, text columns # are only supported REPOSITORY_EXTRA_SEARCH_ATTR = ['repository_text_values.data', diff --git a/db/migrate/20180308094354_create_repository_asset_values.rb b/db/migrate/20180308094354_create_repository_asset_values.rb new file mode 100644 index 000000000..8d3081565 --- /dev/null +++ b/db/migrate/20180308094354_create_repository_asset_values.rb @@ -0,0 +1,14 @@ +class CreateRepositoryAssetValues < ActiveRecord::Migration[5.1] + def change + create_table :repository_asset_values do |t| + t.references :asset, index: true + 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 +end diff --git a/db/schema.rb b/db/schema.rb index 4fac94123..d4082ef50 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: 20180207095200) do +ActiveRecord::Schema.define(version: 20180308094354) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -364,6 +364,17 @@ ActiveRecord::Schema.define(version: 20180207095200) do t.index ["team_id"], name: "index_repositories_on_team_id" end + create_table "repository_asset_values", force: :cascade do |t| + t.bigint "asset_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 ["asset_id"], name: "index_repository_asset_values_on_asset_id" + t.index ["created_by_id"], name: "index_repository_asset_values_on_created_by_id" + t.index ["last_modified_by_id"], name: "index_repository_asset_values_on_last_modified_by_id" + end + create_table "repository_cells", id: :serial, force: :cascade do |t| t.integer "repository_row_id" t.integer "repository_column_id" @@ -877,6 +888,8 @@ ActiveRecord::Schema.define(version: 20180207095200) do add_foreign_key "reports", "users" add_foreign_key "reports", "users", column: "last_modified_by_id" add_foreign_key "repositories", "users", column: "created_by_id" + add_foreign_key "repository_asset_values", "users", column: "created_by_id" + add_foreign_key "repository_asset_values", "users", column: "last_modified_by_id" 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" diff --git a/spec/factories/repository_asset_values.rb b/spec/factories/repository_asset_values.rb new file mode 100644 index 000000000..d8b111455 --- /dev/null +++ b/spec/factories/repository_asset_values.rb @@ -0,0 +1,6 @@ +FactoryBot.define do + factory :repository_asset_value do + created_by { User.first || create(:user) } + last_modified_by { User.first || create(:user) } + end +end diff --git a/spec/models/asset_spec.rb b/spec/models/asset_spec.rb index 36b7d7365..c8e425c50 100644 --- a/spec/models/asset_spec.rb +++ b/spec/models/asset_spec.rb @@ -34,6 +34,8 @@ describe Asset, type: :model do it { should have_one :result_asset } it { should have_one :result } it { should have_one :asset_text_datum } + it { should have_one :repository_asset_value } + it { should have_one :repository_cell } end describe 'Should be a valid object' do diff --git a/spec/models/repository_asset_value_spec.rb b/spec/models/repository_asset_value_spec.rb new file mode 100644 index 000000000..2160df6cd --- /dev/null +++ b/spec/models/repository_asset_value_spec.rb @@ -0,0 +1,49 @@ +require 'rails_helper' + +describe RepositoryAssetValue, type: :model do + it 'should be of class RepositoryAssetValue' do + expect(subject.class).to eq RepositoryAssetValue + end + + describe 'Database table' do + it { should have_db_column :asset_id } + it { should have_db_column :created_at } + it { should have_db_column :updated_at } + it { should have_db_column :created_by_id } + it { should have_db_column :last_modified_by_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 belong_to(:asset).dependent(:destroy) } + it { should have_one :repository_cell } + it { should accept_nested_attributes_for(:repository_cell) } + end + + describe 'Should be a valid object' do + it { should validate_presence_of :repository_cell } + it { should validate_presence_of :asset } + end + + describe '#data' do + let!(:repository) { create :repository } + let!(:repository_column) do + create :repository_column, + name: 'My column', + data_type: :RepositoryAssetValue + end + let!(:repository_row) { create :repository_row, name: 'My row' } + + it 'returns the asset' do + asset = create :asset, file_file_name: 'my file' + repository_asset_value = create :repository_asset_value, + asset: asset, + repository_cell_attributes: { + repository_column: repository_column, + repository_row: repository_row + } + expect(repository_asset_value.reload.formatted.instance).to eq asset + end + end +end