mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-10-02 01:45:38 +08:00
Merge pull request #3422 from okriuchykhin/ok_SCI_5847
Fix repository cell joining and preloading [SCI-5847]
This commit is contained in:
commit
dfa2a7775d
28 changed files with 97 additions and 181 deletions
|
@ -12,7 +12,7 @@ module Api
|
|||
|
||||
def index
|
||||
cells = @inventory_item.repository_cells
|
||||
.preload(@inventory.cell_preload_includes)
|
||||
.preload(value: @inventory.cell_preload_includes)
|
||||
.page(params.dig(:page, :number))
|
||||
.per(params.dig(:page, :size))
|
||||
render jsonapi: cells, each_serializer: InventoryCellSerializer
|
||||
|
|
|
@ -14,7 +14,7 @@ module Api
|
|||
items = @inventory.repository_rows
|
||||
.active
|
||||
.preload(repository_cells: :repository_column)
|
||||
.preload(repository_cells: @inventory.cell_preload_includes)
|
||||
.preload(repository_cells: { value: @inventory.cell_preload_includes })
|
||||
.page(params.dig(:page, :number))
|
||||
.per(params.dig(:page, :size))
|
||||
.order(:id)
|
||||
|
|
|
@ -12,7 +12,7 @@ module Api
|
|||
items =
|
||||
@task.repository_rows
|
||||
.includes(repository_cells: :repository_column)
|
||||
.includes(repository_cells: Extends::REPOSITORY_SEARCH_INCLUDES)
|
||||
.preload(repository_cells: :value)
|
||||
.page(params.dig(:page, :number))
|
||||
.per(params.dig(:page, :size))
|
||||
render jsonapi: items,
|
||||
|
|
|
@ -25,9 +25,10 @@ class MyModuleRepositoriesController < ApplicationController
|
|||
repository_rows = datatable_service.repository_rows
|
||||
rows_view = 'repository_rows/simple_view_index.json'
|
||||
else
|
||||
repository_rows = datatable_service.repository_rows.preload(:repository_columns,
|
||||
:created_by,
|
||||
repository_cells: @repository.cell_preload_includes)
|
||||
repository_rows = datatable_service.repository_rows
|
||||
.preload(:repository_columns,
|
||||
:created_by,
|
||||
repository_cells: { value: @repository.cell_preload_includes })
|
||||
rows_view = 'repository_rows/index.json'
|
||||
end
|
||||
@repository_rows = repository_rows.page(page).per(per_page)
|
||||
|
|
|
@ -19,10 +19,11 @@ class MyModuleRepositorySnapshotsController < ApplicationController
|
|||
repository_rows = datatable_service.repository_rows
|
||||
rows_view = 'repository_rows/simple_view_index.json'
|
||||
else
|
||||
repository_rows = datatable_service.repository_rows
|
||||
.preload(:repository_columns,
|
||||
:created_by,
|
||||
repository_cells: @repository_snapshot.cell_preload_includes)
|
||||
repository_rows =
|
||||
datatable_service.repository_rows
|
||||
.preload(:repository_columns,
|
||||
:created_by,
|
||||
repository_cells: { value: @repository_snapshot.cell_preload_includes })
|
||||
rows_view = 'repository_rows/snapshot_index.json'
|
||||
end
|
||||
@repository_rows = repository_rows.page(page).per(per_page)
|
||||
|
|
|
@ -23,7 +23,7 @@ class RepositoryRowsController < ApplicationController
|
|||
@repository_rows = datatable_service.repository_rows
|
||||
.preload(:repository_columns,
|
||||
:created_by,
|
||||
repository_cells: @repository.cell_preload_includes)
|
||||
repository_cells: { value: @repository.cell_preload_includes })
|
||||
.page(page)
|
||||
.per(per_page)
|
||||
|
||||
|
|
|
@ -101,10 +101,9 @@ module RepositoryDatatableHelper
|
|||
end
|
||||
|
||||
def display_cell_value(cell, team)
|
||||
value_name = cell.repository_column.data_type.demodulize.underscore
|
||||
serializer_class = "RepositoryDatatable::#{cell.repository_column.data_type}Serializer".constantize
|
||||
serializer_class.new(
|
||||
cell.__send__(value_name),
|
||||
cell.value,
|
||||
scope: { team: team, user: current_user, column: cell.repository_column }
|
||||
).serializable_hash
|
||||
end
|
||||
|
|
|
@ -93,7 +93,7 @@ class Repository < RepositoryBase
|
|||
repository_rows = repository_rows.or(readable_rows.where(id: matched_by_user))
|
||||
|
||||
Extends::REPOSITORY_EXTRA_SEARCH_ATTR.each do |_data_type, config|
|
||||
custom_cell_matches = repository_rows.joins(repository_cells: config[:includes])
|
||||
custom_cell_matches = repository_rows.joins(config[:includes])
|
||||
.where_attributes_like(config[:field], query, options)
|
||||
repository_rows = repository_rows.or(readable_rows.where(id: custom_cell_matches))
|
||||
end
|
||||
|
@ -201,14 +201,6 @@ class Repository < RepositoryBase
|
|||
new_repo
|
||||
end
|
||||
|
||||
def cell_preload_includes
|
||||
cell_includes = []
|
||||
repository_columns.pluck(:data_type).each do |data_type|
|
||||
cell_includes << data_type.constantize::PRELOAD_INCLUDE
|
||||
end
|
||||
cell_includes
|
||||
end
|
||||
|
||||
def import_records(sheet, mappings, user)
|
||||
importer = RepositoryImportParser::Importer.new(sheet, mappings, user, self)
|
||||
importer.run
|
||||
|
|
|
@ -18,8 +18,8 @@ class RepositoryAssetValue < ApplicationRecord
|
|||
validates :asset, :repository_cell, presence: true
|
||||
|
||||
SORTABLE_COLUMN_NAME = 'active_storage_blobs.filename'
|
||||
SORTABLE_VALUE_INCLUDE = { repository_asset_value: { asset: { file_attachment: :blob } } }.freeze
|
||||
PRELOAD_INCLUDE = { repository_asset_value: { asset: { file_attachment: :blob } } }.freeze
|
||||
EXTRA_SORTABLE_VALUE_INCLUDE = { asset: { file_attachment: :blob } }.freeze
|
||||
EXTRA_PRELOAD_INCLUDE = { asset: { file_attachment: :blob } }.freeze
|
||||
|
||||
def formatted
|
||||
asset.file_name
|
||||
|
|
|
@ -24,7 +24,10 @@ class RepositoryBase < ApplicationRecord
|
|||
def cell_preload_includes
|
||||
cell_includes = []
|
||||
repository_columns.pluck(:data_type).each do |data_type|
|
||||
cell_includes << data_type.constantize::PRELOAD_INCLUDE
|
||||
value_class = data_type.constantize
|
||||
next unless value_class.const_defined?('EXTRA_PRELOAD_INCLUDE')
|
||||
|
||||
cell_includes << value_class::EXTRA_PRELOAD_INCLUDE
|
||||
end
|
||||
cell_includes
|
||||
end
|
||||
|
|
|
@ -5,106 +5,32 @@ class RepositoryCell < ApplicationRecord
|
|||
|
||||
belongs_to :repository_row
|
||||
belongs_to :repository_column
|
||||
belongs_to :value, polymorphic: true,
|
||||
inverse_of: :repository_cell,
|
||||
dependent: :destroy
|
||||
belongs_to :repository_text_value,
|
||||
(lambda do
|
||||
includes(:repository_cell)
|
||||
.where(repository_cells: { value_type: 'RepositoryTextValue' })
|
||||
end),
|
||||
optional: true, foreign_key: :value_id, inverse_of: :repository_cell
|
||||
belongs_to :repository_number_value,
|
||||
(lambda do
|
||||
includes(:repository_cell)
|
||||
.where(repository_cells: { value_type: 'RepositoryNumberValue' })
|
||||
end),
|
||||
optional: true, foreign_key: :value_id, inverse_of: :repository_cell
|
||||
belongs_to :repository_date_value,
|
||||
(lambda do
|
||||
includes(:repository_cell)
|
||||
.where(repository_cells: { value_type: 'RepositoryDateTimeValueBase' })
|
||||
end),
|
||||
optional: true, foreign_key: :value_id, inverse_of: :repository_cell
|
||||
belongs_to :repository_list_value,
|
||||
(lambda do
|
||||
includes(:repository_cell)
|
||||
.where(repository_cells: { value_type: 'RepositoryListValue' })
|
||||
end),
|
||||
optional: true, foreign_key: :value_id, inverse_of: :repository_cell
|
||||
belongs_to :repository_asset_value,
|
||||
(lambda do
|
||||
includes(:repository_cell)
|
||||
.where(repository_cells: { value_type: 'RepositoryAssetValue' })
|
||||
end),
|
||||
optional: true, foreign_key: :value_id, inverse_of: :repository_cell
|
||||
belongs_to :value, polymorphic: true, inverse_of: :repository_cell, dependent: :destroy
|
||||
|
||||
belongs_to :repository_status_value,
|
||||
(lambda do
|
||||
includes(:repository_cell)
|
||||
.where(repository_cells: { value_type: 'RepositoryStatusValue' })
|
||||
end),
|
||||
optional: true, foreign_key: :value_id, inverse_of: :repository_cell
|
||||
|
||||
belongs_to :repository_checklist_value,
|
||||
(lambda do
|
||||
includes(:repository_cell)
|
||||
.where(repository_cells: { value_type: 'RepositoryChecklistValue' })
|
||||
end),
|
||||
optional: true, foreign_key: :value_id, inverse_of: :repository_cell
|
||||
|
||||
belongs_to :repository_date_time_value_base,
|
||||
(lambda do
|
||||
includes(:repository_cell)
|
||||
.where(repository_cells: { value_type: 'RepositoryDateTimeValueBase' })
|
||||
end),
|
||||
optional: true, foreign_key: :value_id, inverse_of: :repository_cell
|
||||
|
||||
belongs_to :repository_date_time_value,
|
||||
(lambda do
|
||||
includes(:repository_cell)
|
||||
.where(repository_cells: { value_type: 'RepositoryDateTimeValueBase' })
|
||||
end),
|
||||
optional: true, foreign_key: :value_id, inverse_of: :repository_cell
|
||||
|
||||
belongs_to :repository_time_value,
|
||||
(lambda do
|
||||
includes(:repository_cell)
|
||||
.where(repository_cells: { value_type: 'RepositoryDateTimeValueBase' })
|
||||
end),
|
||||
optional: true, foreign_key: :value_id, inverse_of: :repository_cell
|
||||
|
||||
belongs_to :repository_date_time_range_value_base,
|
||||
(lambda do
|
||||
includes(:repository_cell)
|
||||
.where(repository_cells: { value_type: 'RepositoryDateTimeRangeValueBase' })
|
||||
end),
|
||||
optional: true, foreign_key: :value_id, inverse_of: :repository_cell
|
||||
|
||||
belongs_to :repository_date_time_range_value,
|
||||
(lambda do
|
||||
includes(:repository_cell)
|
||||
.where(repository_cells: { value_type: 'RepositoryDateTimeRangeValueBase' })
|
||||
end),
|
||||
optional: true, foreign_key: :value_id, inverse_of: :repository_cell
|
||||
|
||||
belongs_to :repository_date_range_value,
|
||||
(lambda do
|
||||
includes(:repository_cell)
|
||||
.where(repository_cells: { value_type: 'RepositoryDateTimeRangeValueBase' })
|
||||
end),
|
||||
optional: true, foreign_key: :value_id, inverse_of: :repository_cell
|
||||
|
||||
belongs_to :repository_time_range_value,
|
||||
(lambda do
|
||||
includes(:repository_cell)
|
||||
.where(repository_cells: { value_type: 'RepositoryDateTimeRangeValueBase' })
|
||||
end),
|
||||
optional: true, foreign_key: :value_id, inverse_of: :repository_cell
|
||||
{
|
||||
repository_text: 'RepositoryTextValue',
|
||||
repository_number: 'RepositoryNumberValue',
|
||||
repository_list: 'RepositoryListValue',
|
||||
repository_asset: 'RepositoryAssetValue',
|
||||
repository_status: 'RepositoryStatusValue',
|
||||
repository_checklist: 'RepositoryChecklistValue',
|
||||
repository_date_time: 'RepositoryDateTimeValueBase',
|
||||
repository_time: 'RepositoryDateTimeValueBase',
|
||||
repository_date: 'RepositoryDateTimeValueBase',
|
||||
repository_date_time_range: 'RepositoryDateTimeRangeValueBase',
|
||||
repository_time_range: 'RepositoryDateTimeRangeValueBase',
|
||||
repository_date_range: 'RepositoryDateTimeRangeValueBase'
|
||||
}.each do |relation, class_name|
|
||||
belongs_to "#{relation}_value".to_sym,
|
||||
(lambda do |repository_cell|
|
||||
repository_cell.value_type == class_name ? self : none
|
||||
end),
|
||||
optional: true, foreign_key: :value_id, inverse_of: :repository_cell
|
||||
end
|
||||
|
||||
validates :repository_column,
|
||||
inclusion: { in: (lambda do |cell|
|
||||
cell.repository_row&.repository&.repository_columns || []
|
||||
inclusion: { in: (lambda do |repository_cell|
|
||||
repository_cell.repository_row&.repository&.repository_columns || []
|
||||
end) },
|
||||
unless: :importing
|
||||
validates :repository_column, presence: true
|
||||
|
|
|
@ -14,8 +14,8 @@ class RepositoryChecklistValue < ApplicationRecord
|
|||
validates :repository_checklist_items, presence: true
|
||||
|
||||
SORTABLE_COLUMN_NAME = 'repository_checklist_items.data'
|
||||
SORTABLE_VALUE_INCLUDE = { repository_checklist_value: :repository_checklist_items }.freeze
|
||||
PRELOAD_INCLUDE = { repository_checklist_value: :repository_checklist_items }.freeze
|
||||
EXTRA_SORTABLE_VALUE_INCLUDE = :repository_checklist_items
|
||||
EXTRA_PRELOAD_INCLUDE = :repository_checklist_items
|
||||
|
||||
def formatted(separator: ' | ')
|
||||
repository_checklist_items.pluck(:data).join(separator)
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class RepositoryDateRangeValue < RepositoryDateTimeRangeValueBase
|
||||
PRELOAD_INCLUDE = :repository_date_range_value
|
||||
|
||||
def data_changed?(new_data)
|
||||
data = new_data.is_a?(String) ? JSON.parse(new_data).symbolize_keys : new_data
|
||||
st = Time.zone.parse(data[:start_time])
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class RepositoryDateTimeRangeValue < RepositoryDateTimeRangeValueBase
|
||||
PRELOAD_INCLUDE = :repository_date_time_range_value
|
||||
|
||||
def data_changed?(new_data)
|
||||
data = new_data.is_a?(String) ? JSON.parse(new_data).symbolize_keys : new_data
|
||||
st = Time.zone.parse(data[:start_time])
|
||||
|
|
|
@ -13,7 +13,6 @@ class RepositoryDateTimeRangeValueBase < ApplicationRecord
|
|||
validates :repository_cell, :start_time, :end_time, :type, presence: true
|
||||
|
||||
SORTABLE_COLUMN_NAME = 'repository_date_time_range_values.start_time'
|
||||
SORTABLE_VALUE_INCLUDE = :repository_date_time_range_value_base
|
||||
|
||||
def data
|
||||
[start_time, end_time].compact.join(' - ')
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class RepositoryDateTimeValue < RepositoryDateTimeValueBase
|
||||
PRELOAD_INCLUDE = :repository_date_time_value
|
||||
|
||||
def data_changed?(new_data)
|
||||
new_time = Time.zone.parse(new_data)
|
||||
new_time.to_i != data.to_i
|
||||
|
|
|
@ -13,7 +13,6 @@ class RepositoryDateTimeValueBase < ApplicationRecord
|
|||
validates :repository_cell, :data, :type, presence: true
|
||||
|
||||
SORTABLE_COLUMN_NAME = 'repository_date_time_values.data'
|
||||
SORTABLE_VALUE_INCLUDE = :repository_date_time_value_base
|
||||
|
||||
def formatted(format)
|
||||
I18n.l(data, format: format)
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class RepositoryDateValue < RepositoryDateTimeValueBase
|
||||
PRELOAD_INCLUDE = :repository_date_value
|
||||
|
||||
def data_changed?(new_data)
|
||||
new_time = Time.zone.parse(new_data)
|
||||
new_time.to_date != data.to_date
|
||||
|
|
|
@ -20,8 +20,8 @@ class RepositoryListValue < ApplicationRecord
|
|||
end)
|
||||
|
||||
SORTABLE_COLUMN_NAME = 'repository_list_items.data'
|
||||
SORTABLE_VALUE_INCLUDE = { repository_list_value: :repository_list_item }.freeze
|
||||
PRELOAD_INCLUDE = { repository_list_value: :repository_list_item }.freeze
|
||||
EXTRA_SORTABLE_VALUE_INCLUDE = :repository_list_item
|
||||
EXTRA_PRELOAD_INCLUDE = :repository_list_item
|
||||
|
||||
def formatted
|
||||
data.to_s
|
||||
|
|
|
@ -11,8 +11,6 @@ class RepositoryNumberValue < ApplicationRecord
|
|||
validates :repository_cell, :data, presence: true
|
||||
|
||||
SORTABLE_COLUMN_NAME = 'repository_number_values.data'
|
||||
SORTABLE_VALUE_INCLUDE = :repository_number_value
|
||||
PRELOAD_INCLUDE = :repository_number_value
|
||||
|
||||
def formatted
|
||||
data.to_s
|
||||
|
|
|
@ -13,16 +13,35 @@ class RepositoryRow < ApplicationRecord
|
|||
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'
|
||||
belongs_to :archived_by,
|
||||
foreign_key: :archived_by_id,
|
||||
class_name: 'User',
|
||||
inverse_of: :archived_repository_rows,
|
||||
optional: true
|
||||
belongs_to :restored_by,
|
||||
foreign_key: :restored_by_id,
|
||||
class_name: 'User',
|
||||
inverse_of: :restored_repository_rows,
|
||||
optional: true
|
||||
has_many :repository_cells, -> { order(:id) }, dependent: :destroy
|
||||
has_many :repository_cells, -> { order(:id) }, inverse_of: :repository_row, dependent: :destroy
|
||||
|
||||
{
|
||||
repository_text: 'RepositoryTextValue',
|
||||
repository_number: 'RepositoryNumberValue',
|
||||
repository_list: 'RepositoryListValue',
|
||||
repository_asset: 'RepositoryAssetValue',
|
||||
repository_status: 'RepositoryStatusValue',
|
||||
repository_checklist: 'RepositoryChecklistValue',
|
||||
repository_date_time: 'RepositoryDateTimeValue',
|
||||
repository_time: 'RepositoryTimeValue',
|
||||
repository_date: 'RepositoryDateValue',
|
||||
repository_date_time_range: 'RepositoryDateTimeRangeValue',
|
||||
repository_time_range: 'RepositoryTimeRangeValue',
|
||||
repository_date_range: 'RepositoryDateRangeValue'
|
||||
}.each do |relation, class_name|
|
||||
has_many "#{relation}_cells".to_sym, -> { where(value_type: class_name) }, class_name: 'RepositoryCell',
|
||||
inverse_of: :repository_row
|
||||
has_many "#{relation}_values".to_sym, class_name: class_name, through: "#{relation}_cells".to_sym,
|
||||
source: :value, source_type: class_name
|
||||
end
|
||||
|
||||
has_many :repository_columns, through: :repository_cells
|
||||
has_many :my_module_repository_rows,
|
||||
inverse_of: :repository_row, dependent: :destroy
|
||||
|
|
|
@ -12,8 +12,8 @@ class RepositoryStatusValue < ApplicationRecord
|
|||
validates :repository_cell, :repository_status_item, presence: true
|
||||
|
||||
SORTABLE_COLUMN_NAME = 'repository_status_items.status'
|
||||
SORTABLE_VALUE_INCLUDE = { repository_status_value: :repository_status_item }.freeze
|
||||
PRELOAD_INCLUDE = { repository_status_value: :repository_status_item }.freeze
|
||||
EXTRA_SORTABLE_VALUE_INCLUDE = :repository_status_item
|
||||
EXTRA_PRELOAD_INCLUDE = :repository_status_item
|
||||
|
||||
def formatted
|
||||
data
|
||||
|
|
|
@ -14,8 +14,6 @@ class RepositoryTextValue < ApplicationRecord
|
|||
validates :data, presence: true, length: { maximum: Constants::TEXT_MAX_LENGTH }
|
||||
|
||||
SORTABLE_COLUMN_NAME = 'repository_text_values.data'
|
||||
SORTABLE_VALUE_INCLUDE = :repository_text_value
|
||||
PRELOAD_INCLUDE = :repository_text_value
|
||||
|
||||
def formatted
|
||||
data
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class RepositoryTimeRangeValue < RepositoryDateTimeRangeValueBase
|
||||
PRELOAD_INCLUDE = :repository_time_range_value
|
||||
|
||||
def data_changed?(new_data)
|
||||
data = new_data.is_a?(String) ? JSON.parse(new_data).symbolize_keys : new_data
|
||||
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class RepositoryTimeValue < RepositoryDateTimeValueBase
|
||||
PRELOAD_INCLUDE = :repository_time_value
|
||||
|
||||
def data_changed?(new_data)
|
||||
new_time = Time.zone.parse(new_data)
|
||||
new_time.min != data.min || new_time.hour != data.hour
|
||||
|
|
|
@ -91,7 +91,7 @@ class RepositoryDatatableService
|
|||
Extends::REPOSITORY_EXTRA_SEARCH_ATTR.each do |data_type, config|
|
||||
next unless data_types.include?(data_type.to_s)
|
||||
|
||||
custom_cell_matches = repository_rows.joins(repository_cells: config[:includes])
|
||||
custom_cell_matches = repository_rows.joins(config[:includes])
|
||||
.where_attributes_like(config[:field], search_value)
|
||||
results = results.or(repository_rows.where(id: custom_cell_matches))
|
||||
end
|
||||
|
@ -139,37 +139,38 @@ class RepositoryDatatableService
|
|||
col_order = service.load_state.state['ColReorder']
|
||||
column_id = col_order[column_index].to_i
|
||||
|
||||
if @sortable_columns[column_id - 1] == 'assigned'
|
||||
case @sortable_columns[column_id - 1]
|
||||
when 'assigned'
|
||||
return records if @my_module && @params[:assigned] == 'assigned'
|
||||
|
||||
records.order("assigned_my_modules_count #{dir}")
|
||||
elsif @sortable_columns[column_id - 1] == 'repository_cell.value'
|
||||
when 'repository_cell.value'
|
||||
id = @mappings.key(column_id.to_s)
|
||||
sorting_column = RepositoryColumn.find_by(id: id)
|
||||
sorting_column = @repository.repository_columns.find_by(id: id)
|
||||
return records unless sorting_column
|
||||
|
||||
sorting_data_type = sorting_column.data_type.constantize
|
||||
cells = sorting_data_type.joins(:repository_cell)
|
||||
.where('repository_cells.repository_column_id': sorting_column.id)
|
||||
if sorting_data_type.const_defined?('EXTRA_SORTABLE_VALUE_INCLUDE')
|
||||
cells = cells.joins(sorting_data_type::EXTRA_SORTABLE_VALUE_INCLUDE)
|
||||
end
|
||||
|
||||
cells = if sorting_column.repository_checklist_value?
|
||||
RepositoryCell.joins(sorting_data_type::SORTABLE_VALUE_INCLUDE)
|
||||
.where('repository_cells.repository_column_id': sorting_column.id)
|
||||
.select("repository_cells.repository_row_id,
|
||||
STRING_AGG(
|
||||
#{sorting_data_type::SORTABLE_COLUMN_NAME}, ' '
|
||||
ORDER BY #{sorting_data_type::SORTABLE_COLUMN_NAME}) AS value")
|
||||
.group('repository_cells.repository_row_id')
|
||||
|
||||
cells
|
||||
.select("repository_cells.repository_row_id, \
|
||||
STRING_AGG(#{sorting_data_type::SORTABLE_COLUMN_NAME}, ' ' \
|
||||
ORDER BY #{sorting_data_type::SORTABLE_COLUMN_NAME}) AS value")
|
||||
.group('repository_cells.repository_row_id')
|
||||
else
|
||||
RepositoryCell.joins(sorting_data_type::SORTABLE_VALUE_INCLUDE)
|
||||
.where('repository_cells.repository_column_id': sorting_column.id)
|
||||
.select("repository_cells.repository_row_id,
|
||||
#{sorting_data_type::SORTABLE_COLUMN_NAME} AS value")
|
||||
cells
|
||||
.select("repository_cells.repository_row_id, #{sorting_data_type::SORTABLE_COLUMN_NAME} AS value")
|
||||
end
|
||||
|
||||
records.joins("LEFT OUTER JOIN (#{cells.to_sql}) AS values ON values.repository_row_id = repository_rows.id")
|
||||
.group('values.value')
|
||||
.order("values.value #{dir}")
|
||||
elsif @sortable_columns[column_id - 1] == 'users.full_name'
|
||||
when 'users.full_name'
|
||||
records.group('users.full_name').order("users.full_name #{dir}")
|
||||
else
|
||||
records.group(@sortable_columns[column_id - 1]).order("#{@sortable_columns[column_id - 1]} #{dir}")
|
||||
|
|
|
@ -41,7 +41,7 @@ class RepositorySnapshotDatatableService < RepositoryDatatableService
|
|||
Extends::REPOSITORY_EXTRA_SEARCH_ATTR.each do |data_type, config|
|
||||
next unless data_types.include?(data_type.to_s)
|
||||
|
||||
custom_cell_matches = repository_rows.joins(repository_cells: config[:includes])
|
||||
custom_cell_matches = repository_rows.joins(config[:includes])
|
||||
.where_attributes_like(config[:field], search_value)
|
||||
results = results.or(repository_rows.where(id: custom_cell_matches))
|
||||
end
|
||||
|
|
|
@ -69,32 +69,24 @@ class Extends
|
|||
# Extra attributes used for search in repositories, 'filed_name' => include_hash
|
||||
REPOSITORY_EXTRA_SEARCH_ATTR = {
|
||||
RepositoryTextValue: {
|
||||
field: 'repository_text_values.data', includes: :repository_text_value
|
||||
field: 'repository_text_values.data', includes: :repository_text_values
|
||||
}, RepositoryNumberValue: {
|
||||
field: 'repository_number_values.data', includes: :repository_number_value
|
||||
field: 'repository_number_values.data', includes: :repository_number_values
|
||||
}, RepositoryListValue: {
|
||||
field: 'repository_list_items.data',
|
||||
includes: { repository_list_value: :repository_list_item }
|
||||
includes: { repository_list_values: :repository_list_item }
|
||||
}, RepositoryChecklistValue: {
|
||||
field: 'repository_checklist_items.data',
|
||||
includes: { repository_checklist_value: { repository_checklist_items_values: :repository_checklist_item } }
|
||||
includes: { repository_checklist_values: { repository_checklist_items_values: :repository_checklist_item } }
|
||||
}, RepositoryStatusValue: {
|
||||
field: 'repository_status_items.status',
|
||||
includes: { repository_status_value: :repository_status_item }
|
||||
includes: { repository_status_values: :repository_status_item }
|
||||
}, RepositoryAssetValue: {
|
||||
field: 'active_storage_blobs.filename',
|
||||
includes: { repository_asset_value: { asset: { file_attachment: :blob } } }
|
||||
includes: { repository_asset_values: { asset: { file_attachment: :blob } } }
|
||||
}
|
||||
}
|
||||
|
||||
# Array of includes used in search query for repository rows
|
||||
REPOSITORY_SEARCH_INCLUDES = [:repository_text_value,
|
||||
:repository_number_value,
|
||||
repository_list_value: :repository_list_item,
|
||||
repository_checklist_value: :repository_checklist_items,
|
||||
repository_status_value: :repository_status_item,
|
||||
repository_asset_value: { asset: { file_attachment: :blob } }]
|
||||
|
||||
# Array of preload relations used in search query for repository rows
|
||||
REPOSITORY_ROWS_PRELOAD_RELATIONS = []
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue