Merge pull request #2304 from okriuchykhin/ok_SCI_4204

Refactor repository cell cloning to support all data types [SCI-4204]
This commit is contained in:
Alex Kriuchykhin 2020-01-15 13:04:50 +01:00 committed by GitHub
commit da26d8a018
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 132 additions and 184 deletions

View file

@ -384,10 +384,8 @@ class MyModulesController < ApplicationController
@draw = params[:draw].to_i
per_page = params[:length] == '-1' ? 100 : params[:length].to_i
page = (params[:start].to_i / per_page) + 1
datatable_service = RepositoryDatatableService.new(@repository,
params,
current_user,
@my_module)
datatable_service = RepositoryDatatableService.new(@repository, params, current_user, @my_module)
@all_rows_count = datatable_service.all_count
@columns_mappings = datatable_service.mappings
@repository_rows = datatable_service.repository_rows

View file

@ -147,7 +147,7 @@ class RepositoryRowsController < ApplicationController
def copy_records
duplicate_service = RepositoryActions::DuplicateRows.new(
current_user, @repository, params[:selected_rows]
current_user, @repository, copy_records_params
)
duplicate_service.call
render json: {
@ -223,6 +223,11 @@ class RepositoryRowsController < ApplicationController
params.permit(selected_rows: []).to_h[:selected_rows]
end
def copy_records_params
process_ids = params[:selected_rows].map(&:to_i).uniq
@repository.repository_rows.where(id: process_ids).pluck(:id)
end
def load_available_rows(query)
@repository.repository_rows
.includes(:repository_cells)

View file

@ -1,8 +0,0 @@
# frozen_string_literal: true
class RepositoryCellValuesChecklistItem < ApplicationRecord
belongs_to :repository_checklist_item
belongs_to :repository_checklist_value
validates :repository_checklist_item, :repository_checklist_value, presence: true
end

View file

@ -11,6 +11,6 @@ class RepositoryChecklistItem < ApplicationRecord
inverse_of: :created_repository_checklist_types
belongs_to :last_modified_by, foreign_key: 'last_modified_by_id', class_name: 'User',
inverse_of: :modified_repository_checklist_types
has_many :repository_cell_values_checklist_items, dependent: :destroy
has_many :repository_checklist_values, through: :repository_cell_values_checklist_items
has_many :repository_checklist_items_values, dependent: :destroy
has_many :repository_checklist_values, through: :repository_checklist_items_values
end

View file

@ -0,0 +1,14 @@
# frozen_string_literal: true
class RepositoryChecklistItemsValue < ApplicationRecord
belongs_to :repository_checklist_item
belongs_to :repository_checklist_value
validates :repository_checklist_item, :repository_checklist_value, presence: true
after_destroy :destroy_empty_value
def destroy_empty_value
repository_checklist_value.destroy! if repository_checklist_value.repository_checklist_items_values.blank?
end
end

View file

@ -6,11 +6,12 @@ class RepositoryChecklistValue < ApplicationRecord
belongs_to :last_modified_by, foreign_key: 'last_modified_by_id', class_name: 'User',
inverse_of: :modified_repository_checklist_values
has_one :repository_cell, as: :value, dependent: :destroy, inverse_of: :value
has_many :repository_cell_values_checklist_items, dependent: :destroy
has_many :repository_checklist_items, through: :repository_cell_values_checklist_items
has_many :repository_checklist_items_values, dependent: :destroy
has_many :repository_checklist_items, -> { order('data ASC') }, through: :repository_checklist_items_values
accepts_nested_attributes_for :repository_cell
validates :repository_cell, presence: true
validates :repository_checklist_items, presence: true
SORTABLE_COLUMN_NAME = 'repository_checklist_items.data'
SORTABLE_VALUE_INCLUDE = { repository_checklist_value: :repository_checklist_items }.freeze
@ -24,7 +25,7 @@ class RepositoryChecklistValue < ApplicationRecord
end
def data
repository_checklist_items.map { |i| { value: i.id, label: i.data } }.sort_by { |item| item[:label] }
repository_checklist_items.map { |i| { value: i.id, label: i.data } }
end
def data_changed?(new_data)
@ -32,10 +33,10 @@ class RepositoryChecklistValue < ApplicationRecord
end
def update_data!(new_data, user)
repository_cell_values_checklist_items.destroy_all
repository_checklist_items_values.destroy_all
repository_cell.repository_column
.repository_checklist_items.where(id: JSON.parse(new_data)).find_each do |item|
repository_cell_values_checklist_items.create!(repository_checklist_item: item)
repository_checklist_items_values.create!(repository_checklist_item: item)
end
self.last_modified_by = user
save!
@ -46,7 +47,7 @@ class RepositoryChecklistValue < ApplicationRecord
value.repository_cell
.repository_column
.repository_checklist_items.where(id: JSON.parse(payload)).find_each do |item|
value.repository_cell_values_checklist_items.new(repository_checklist_item: item)
value.repository_checklist_items_values.new(repository_checklist_item: item)
end
value
end

View file

@ -174,7 +174,7 @@ module ModelExporters
def get_cell_value_checklist(cell)
return unless cell.value_type == 'RepositoryChecklistValue'
cell.value.repository_cell_values_checklist_items
cell.value.repository_checklist_items_values
end
end
end

View file

@ -2,70 +2,34 @@
module RepositoryActions
class DuplicateCell
def initialize(cell, new_row, user, team)
def initialize(cell, new_row, user)
@cell = cell
@new_row = new_row
@user = user
@team = team
end
def call
__send__("duplicate_#{@cell.value_type.split('::').last.underscore}")
new_value = @cell.value.dup
new_value.repository_cell = RepositoryCell.new(repository_row: @new_row,
repository_column: @cell.repository_column)
new_value.created_by = @user
new_value.last_modified_by = @user
if respond_to?("#{@cell.value_type.split('::').last.underscore}_extra_attributes", true)
__send__("#{@cell.value_type.split('::').last.underscore}_extra_attributes", new_value)
end
new_value.save!
end
private
def duplicate_repository_list_value
old_value = @cell.value
RepositoryListValue.create(
old_value.attributes.merge(
id: nil, created_by: @user, last_modified_by: @user,
repository_cell_attributes: {
repository_row: @new_row,
repository_column: @cell.repository_column
}
)
)
def repository_asset_value_extra_attributes(value)
new_asset = @cell.value.asset.duplicate
value.asset = new_asset
end
def duplicate_repository_text_value
old_value = @cell.value
RepositoryTextValue.create(
old_value.attributes.merge(
id: nil, created_by: @user, last_modified_by: @user,
repository_cell_attributes: {
repository_row: @new_row,
repository_column: @cell.repository_column
}
)
)
end
def duplicate_repository_asset_value
old_value = @cell.value
new_asset = old_value.asset.duplicate
RepositoryAssetValue.create(
old_value.attributes.merge(
id: nil, asset: new_asset, created_by: @user, last_modified_by: @user,
repository_cell_attributes: {
repository_row: @new_row,
repository_column: @cell.repository_column
}
)
)
end
def duplicate_repository_date_value
old_value = @cell.value
RepositoryDateTimeValue.create(
old_value.attributes.merge(
id: nil, created_by: @user, last_modified_by: @user,
repository_cell_attributes: {
repository_row: @new_row,
repository_column: @cell.repository_column
}
)
)
def repository_checklist_value_extra_attributes(value)
value.repository_checklist_items = @cell.value.repository_checklist_items
end
end
end

View file

@ -6,7 +6,7 @@ module RepositoryActions
def initialize(user, repository, rows_ids = [])
@user = user
@repository = repository
@rows_to_duplicate = sanitize_rows_to_duplicate(rows_ids)
@rows_to_duplicate = rows_ids
@number_of_duplicated_items = 0
end
@ -18,23 +18,21 @@ module RepositoryActions
private
def sanitize_rows_to_duplicate(rows_ids)
process_ids = rows_ids.map(&:to_i).uniq
@repository.repository_rows.where(id: process_ids).pluck(:id)
end
def duplicate_row(id)
row = RepositoryRow.find_by_id(id)
new_row = RepositoryRow.new(
row.attributes.merge(new_row_attributes(row.name, @user.id))
)
RepositoryRow.transaction do
row = @repository.repository_rows.find_by(id: id)
return unless row
new_row = RepositoryRow.create!(
row.attributes.merge(new_row_attributes(row.name, @user.id))
)
if new_row.save
@number_of_duplicated_items += 1
row.repository_cells.each do |cell|
duplicate_repository_cell(cell, new_row)
RepositoryActions::DuplicateCell.new(cell, new_row, @user).call
end
@number_of_duplicated_items += 1
Activities::CreateActivityService
.call(activity_type: :copy_inventory_item,
owner: @user,
@ -52,11 +50,5 @@ module RepositoryActions
created_at: timestamp,
updated_at: timestamp }
end
def duplicate_repository_cell(cell, new_row)
RepositoryActions::DuplicateCell.new(
cell, new_row, @user, @repository.team
).call
end
end
end

View file

@ -44,18 +44,13 @@ class RepositoryDatatableService
'AND "my_module_repository_rows"."my_module_id" = ' + @my_module.id.to_s
)
end
repository_rows = repository_rows
.select('repository_rows.*')
.select('COUNT(my_module_repository_rows.id) AS "assigned_my_modules_count"')
.group('repository_rows.id')
repository_rows = repository_rows.select('COUNT(my_module_repository_rows.id) AS "assigned_my_modules_count"')
else
repository_rows = repository_rows
.left_outer_joins(my_module_repository_rows: { my_module: :experiment })
.select('repository_rows.*')
.select('COUNT(my_module_repository_rows.id) AS "assigned_my_modules_count"')
.select('COUNT(DISTINCT my_modules.experiment_id) AS "assigned_experiments_count"')
.select('COUNT(DISTINCT experiments.project_id) AS "assigned_projects_count"')
.group('repository_rows.id')
end
@repository_rows = sort_rows(order_obj, repository_rows)
@ -91,6 +86,9 @@ class RepositoryDatatableService
end
repository_rows.left_outer_joins(:created_by)
.select('repository_rows.*')
.select('COUNT("repository_rows"."id") OVER() AS filtered_count')
.group('repository_rows.id')
end
def build_conditions(params)

View file

@ -981,7 +981,7 @@ class TeamImporter
if repository_cell.value_type == 'RepositoryChecklistValue'
value_json['repository_value_checklist'].each do |item|
item_id = find_checklist_item_id(item['repository_checklist_item_id']).to_i
RepositoryCellValuesChecklistItem.create!(repository_checklist_value: repository_value,
RepositoryChecklistItemsValue.create!(repository_checklist_value: repository_value,
repository_checklist_item_id: item_id)
end
end

View file

@ -7,5 +7,5 @@ json.data do
@columns_mappings,
@repository.team)
end
json.recordsFiltered @repository_rows.length
json.recordsFiltered @repository_rows.first ? @repository_rows.first.filtered_count : 0
json.recordsTotal @all_rows_count

View file

@ -65,7 +65,7 @@ class Extends
'repository_list_items.data' => { repository_list_value: :repository_list_item },
'repository_checklist_items.data' =>
{ repository_checklist_value:
{ repository_cell_values_checklist_items: :repository_checklist_item } },
{ repository_checklist_items_values: :repository_checklist_item } },
'repository_status_items.status' =>
{ repository_status_value: :repository_status_item },
'active_storage_blobs.filename' =>

View file

@ -19,11 +19,9 @@ class CreateRepositoryChecklists < ActiveRecord::Migration[6.0]
t.timestamps
end
create_table :repository_cell_values_checklist_items do |t|
t.references :repository_checklist_item, null: false, foreign_key: true,
index: { name: :repository_cell_values_checklist_item_id }
t.references :repository_checklist_value, null: false, foreign_key: true,
index: { name: :repository_cell_values_checklist_value_id }
create_table :repository_checklist_items_values do |t|
t.belongs_to :repository_checklist_value, index: { name: 'index_on_repository_checklist_value_id' }
t.belongs_to :repository_checklist_item, index: { name: 'index_on_repository_checklist_item_id' }
t.timestamps
end
end

View file

@ -1133,38 +1133,6 @@ CREATE SEQUENCE public.repository_asset_values_id_seq
ALTER SEQUENCE public.repository_asset_values_id_seq OWNED BY public.repository_asset_values.id;
--
-- Name: repository_cell_values_checklist_items; Type: TABLE; Schema: public; Owner: -
--
CREATE TABLE public.repository_cell_values_checklist_items (
id bigint NOT NULL,
repository_checklist_item_id bigint NOT NULL,
repository_checklist_value_id bigint NOT NULL,
created_at timestamp(6) without time zone NOT NULL,
updated_at timestamp(6) without time zone NOT NULL
);
--
-- Name: repository_cell_values_checklist_items_id_seq; Type: SEQUENCE; Schema: public; Owner: -
--
CREATE SEQUENCE public.repository_cell_values_checklist_items_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
--
-- Name: repository_cell_values_checklist_items_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
--
ALTER SEQUENCE public.repository_cell_values_checklist_items_id_seq OWNED BY public.repository_cell_values_checklist_items.id;
--
-- Name: repository_cells; Type: TABLE; Schema: public; Owner: -
--
@ -1234,6 +1202,38 @@ CREATE SEQUENCE public.repository_checklist_items_id_seq
ALTER SEQUENCE public.repository_checklist_items_id_seq OWNED BY public.repository_checklist_items.id;
--
-- Name: repository_checklist_items_values; Type: TABLE; Schema: public; Owner: -
--
CREATE TABLE public.repository_checklist_items_values (
id bigint NOT NULL,
repository_checklist_value_id bigint,
repository_checklist_item_id bigint,
created_at timestamp(6) without time zone NOT NULL,
updated_at timestamp(6) without time zone NOT NULL
);
--
-- Name: repository_checklist_items_values_id_seq; Type: SEQUENCE; Schema: public; Owner: -
--
CREATE SEQUENCE public.repository_checklist_items_values_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
--
-- Name: repository_checklist_items_values_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
--
ALTER SEQUENCE public.repository_checklist_items_values_id_seq OWNED BY public.repository_checklist_items_values.id;
--
-- Name: repository_checklist_values; Type: TABLE; Schema: public; Owner: -
--
@ -2970,13 +2970,6 @@ ALTER TABLE ONLY public.repositories ALTER COLUMN id SET DEFAULT nextval('public
ALTER TABLE ONLY public.repository_asset_values ALTER COLUMN id SET DEFAULT nextval('public.repository_asset_values_id_seq'::regclass);
--
-- Name: repository_cell_values_checklist_items id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY public.repository_cell_values_checklist_items ALTER COLUMN id SET DEFAULT nextval('public.repository_cell_values_checklist_items_id_seq'::regclass);
--
-- Name: repository_cells id; Type: DEFAULT; Schema: public; Owner: -
--
@ -2991,6 +2984,13 @@ ALTER TABLE ONLY public.repository_cells ALTER COLUMN id SET DEFAULT nextval('pu
ALTER TABLE ONLY public.repository_checklist_items ALTER COLUMN id SET DEFAULT nextval('public.repository_checklist_items_id_seq'::regclass);
--
-- Name: repository_checklist_items_values id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY public.repository_checklist_items_values ALTER COLUMN id SET DEFAULT nextval('public.repository_checklist_items_values_id_seq'::regclass);
--
-- Name: repository_checklist_values id; Type: DEFAULT; Schema: public; Owner: -
--
@ -3545,14 +3545,6 @@ ALTER TABLE ONLY public.repository_asset_values
ADD CONSTRAINT repository_asset_values_pkey PRIMARY KEY (id);
--
-- Name: repository_cell_values_checklist_items repository_cell_values_checklist_items_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public.repository_cell_values_checklist_items
ADD CONSTRAINT repository_cell_values_checklist_items_pkey PRIMARY KEY (id);
--
-- Name: repository_cells repository_cells_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
@ -3569,6 +3561,14 @@ ALTER TABLE ONLY public.repository_checklist_items
ADD CONSTRAINT repository_checklist_items_pkey PRIMARY KEY (id);
--
-- Name: repository_checklist_items_values repository_checklist_items_values_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public.repository_checklist_items_values
ADD CONSTRAINT repository_checklist_items_values_pkey PRIMARY KEY (id);
--
-- Name: repository_checklist_values repository_checklist_values_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
@ -4421,6 +4421,20 @@ CREATE UNIQUE INDEX index_oauth_applications_on_uid ON public.oauth_applications
CREATE INDEX index_on_rep_status_type_id ON public.repository_status_values USING btree (repository_status_item_id);
--
-- Name: index_on_repository_checklist_item_id; Type: INDEX; Schema: public; Owner: -
--
CREATE INDEX index_on_repository_checklist_item_id ON public.repository_checklist_items_values USING btree (repository_checklist_item_id);
--
-- Name: index_on_repository_checklist_value_id; Type: INDEX; Schema: public; Owner: -
--
CREATE INDEX index_on_repository_checklist_value_id ON public.repository_checklist_items_values USING btree (repository_checklist_value_id);
--
-- Name: index_projects_on_archived_by_id; Type: INDEX; Schema: public; Owner: -
--
@ -5695,20 +5709,6 @@ 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_cell_values_checklist_item_id; Type: INDEX; Schema: public; Owner: -
--
CREATE INDEX repository_cell_values_checklist_item_id ON public.repository_cell_values_checklist_items USING btree (repository_checklist_item_id);
--
-- Name: repository_cell_values_checklist_value_id; Type: INDEX; Schema: public; Owner: -
--
CREATE INDEX repository_cell_values_checklist_value_id ON public.repository_cell_values_checklist_items USING btree (repository_checklist_value_id);
--
-- Name: repository_status_items fk_rails_00642f1707; Type: FK CONSTRAINT; Schema: public; Owner: -
--
@ -6901,14 +6901,6 @@ ALTER TABLE ONLY public.oauth_access_tokens
ADD CONSTRAINT fk_rails_ee63f25419 FOREIGN KEY (resource_owner_id) REFERENCES public.users(id);
--
-- Name: repository_cell_values_checklist_items fk_rails_efd3251ebf; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public.repository_cell_values_checklist_items
ADD CONSTRAINT fk_rails_efd3251ebf FOREIGN KEY (repository_checklist_value_id) REFERENCES public.repository_checklist_values(id);
--
-- Name: repository_date_time_range_values fk_rails_efe428fafe; Type: FK CONSTRAINT; Schema: public; Owner: -
--
@ -6933,14 +6925,6 @@ ALTER TABLE ONLY public.report_elements
ADD CONSTRAINT fk_rails_f36eac136b FOREIGN KEY (experiment_id) REFERENCES public.experiments(id);
--
-- Name: repository_cell_values_checklist_items fk_rails_f5260bda13; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public.repository_cell_values_checklist_items
ADD CONSTRAINT fk_rails_f5260bda13 FOREIGN KEY (repository_checklist_item_id) REFERENCES public.repository_checklist_items(id);
--
-- Name: user_projects fk_rails_f58e9073ce; Type: FK CONSTRAINT; Schema: public; Owner: -
--

View file

@ -3,9 +3,11 @@
require 'rails_helper'
RSpec.describe RepositoryChecklistValue, type: :model do
let(:repository_checklist_item) { build :repository_checklist_item }
let(:repository_checklist_value) { build :repository_checklist_value }
it 'is valid' do
repository_checklist_value.repository_checklist_items << repository_checklist_item
expect(repository_checklist_value).to be_valid
end