scinote-web/app/services/repository_datatable_service.rb

180 lines
6.1 KiB
Ruby
Raw Normal View History

class RepositoryDatatableService
2018-03-09 00:36:10 +08:00
attr_reader :repository_rows, :assigned_rows
2018-03-09 00:36:10 +08:00
def initialize(repository, params, mappings, user, my_module = nil)
@mappings = mappings
@repository = repository
2018-03-09 00:36:10 +08:00
@mappings = mappings
@user = user
@my_module = my_module
@params = params
process_query
end
private
2018-03-09 00:36:10 +08:00
def process_query
contitions = build_conditions(@params)
order_obj = contitions[:order_by_column]
search_value = contitions[:search_value]
if search_value.present?
@repository_rows = sort_rows(order_obj, search(search_value))
else
2018-03-09 00:36:10 +08:00
@repository_rows = sort_rows(order_obj, fetch_records)
end
end
def fetch_records
2018-03-09 00:36:10 +08:00
repository_rows = RepositoryRow.preload(:repository_columns,
:created_by,
repository_cells: :value)
.joins(:created_by)
.where(repository: @repository)
if @my_module
@assigned_rows = @my_module.repository_rows
.preload(
:repository_columns,
:created_by,
repository_cells: :value
)
.joins(:created_by)
.where(repository: @repository)
return @assigned_rows if @params[:assigned] == 'assigned'
else
@assigned_rows = repository_rows.joins(
'INNER JOIN my_module_repository_rows ON
(repository_rows.id = my_module_repository_rows.repository_row_id)'
)
end
repository_rows
end
def search(value)
2018-03-09 00:36:10 +08:00
includes_json = {
repository_cells: [:repository_text_value,
repository_list_value: :repository_list_item ]
}
RepositoryRow .left_outer_joins(:created_by)
.left_outer_joins(includes_json)
.where(repository: @repository)
.where_attributes_like(
['repository_rows.name',
'users.full_name',
'repository_text_values.data',
'repository_list_items.data'],
value
)
end
def build_conditions(params)
search_value = params[:search][:value]
2018-03-09 00:36:10 +08:00
order = params[:order].values.first
order_by_column = { column: order[:column].to_i,
dir: order[:dir] }
{ search_value: search_value, order_by_column: order_by_column }
end
def sortable_columns
2018-03-09 00:36:10 +08:00
array = [
'assigned',
2018-03-09 00:36:10 +08:00
'repository_rows.name',
'repository_rows.created_at',
'users.full_name'
]
2018-03-09 00:36:10 +08:00
@repository.repository_columns.count.times do
array << 'repository_cell.value'
end
array
end
def sort_rows(column_obj, records)
dir = %w[DESC ASC].find { |dir| dir == column_obj[:dir].upcase } || 'ASC'
column_index = column_obj[:column]
col_order = @repository.repository_table_states
.find_by_user_id(@user.id)
.state['ColReorder']
column_id = col_order[column_index].to_i
2018-03-09 00:36:10 +08:00
if sortable_columns[column_id - 1] == 'assigned'
return records if @my_module && @params[:assigned] == 'assigned'
if @my_module
# Depending on the sort, order nulls first or
# nulls last on repository_cells association
return records.joins(
"LEFT OUTER JOIN my_module_repository_rows ON
(repository_rows.id = my_module_repository_rows.repository_row_id
AND (my_module_repository_rows.my_module_id = #{@my_module.id} OR
my_module_repository_rows.id IS NULL))"
).order(
"my_module_repository_rows.id NULLS #{sort_null_direction(dir)}"
)
else
return sort_assigned_records(records, dir)
end
elsif sortable_columns[column_id - 1] == 'repository_cell.value'
id = @mappings.key(column_id.to_s)
type = RepositoryColumn.find_by_id(id)
return records unless type
return select_type(type.data_type, records, id, dir)
else
return records.order("#{sortable_columns[column_id - 1]} #{dir}")
end
end
2018-03-09 00:36:10 +08:00
def sort_assigned_records(records, direction)
assigned = records.joins(:my_module_repository_rows).distinct.pluck(:id)
unassigned = records.where.not(id: assigned).pluck(:id)
if direction == 'ASC'
ids = assigned + unassigned
elsif direction == 'DESC'
ids = unassigned + assigned
end
2018-03-09 00:36:10 +08:00
order_by_index = ActiveRecord::Base.send(
:sanitize_sql_array,
["position((',' || repository_rows.id || ',') in ?)",
ids.join(',') + ',']
)
records.order(order_by_index)
end
def select_type(type, records, id, dir)
return filter_by_text_value(
records, id, dir) if type == 'RepositoryTextValue'
return filter_by_list_value(
records, id, dir) if type == 'RepositoryListValue'
end
2018-03-09 00:36:10 +08:00
def sort_null_direction(val)
val == 'ASC' ? 'LAST' : 'FIRST'
end
def filter_by_text_value(records, id, dir)
return records.joins(
"LEFT OUTER JOIN (SELECT repository_cells.repository_row_id,
repository_text_values.data AS value
FROM repository_cells
INNER JOIN repository_text_values
ON repository_text_values.id = repository_cells.value_id
WHERE repository_cells.repository_column_id = #{id}) AS values
ON values.repository_row_id = repository_rows.id"
).order("values.value #{dir}")
end
def filter_by_list_value(records, id, dir)
return records.joins(
"LEFT OUTER JOIN (SELECT repository_cells.repository_row_id,
repository_list_items.data AS value
FROM repository_cells
INNER JOIN repository_list_values
ON repository_list_values.id = repository_cells.value_id
INNER JOIN repository_list_items
ON repository_list_values.repository_list_item_id =
repository_list_items.id
WHERE repository_cells.repository_column_id = #{id}) AS values
ON values.repository_row_id = repository_rows.id"
).order("values.value #{dir}")
end
end