mirror of
https://github.com/astuto/astuto.git
synced 2025-12-15 03:07:52 +01:00
68 lines
2.1 KiB
Ruby
68 lines
2.1 KiB
Ruby
|
|
class ReorderWorkflow
|
||
|
|
attr_accessor :entity_classname, :column_name
|
||
|
|
attr_accessor :entity_id, :src_index, :dst_index
|
||
|
|
|
||
|
|
# This workflow is used by entities which has a "order" column of sort
|
||
|
|
# Given:
|
||
|
|
# entity_classname: the entity class name, e.g. PostStatus
|
||
|
|
# column_name: the name of the db column that contains the order information, e.g. 'order'
|
||
|
|
# entity_id: the id of the entity being reordered
|
||
|
|
# src_index: the current order of the entity
|
||
|
|
# dst_index = the new order of the entity
|
||
|
|
#
|
||
|
|
# The workflow reorders the record with id <entity_id> of entity <entity_classname>
|
||
|
|
# from <src_index> to <dst_index> using <column_name> as the db column that keeps the ordering
|
||
|
|
#
|
||
|
|
# Returns:
|
||
|
|
# A collection of the reordered records, if successful
|
||
|
|
# nil, if unsuccessful
|
||
|
|
|
||
|
|
def initialize(entity_classname: "", column_name: "", entity_id: "", src_index: "", dst_index: "")
|
||
|
|
@entity_classname = entity_classname
|
||
|
|
@column_name = column_name
|
||
|
|
@entity_id = entity_id
|
||
|
|
@src_index = src_index
|
||
|
|
@dst_index = dst_index
|
||
|
|
end
|
||
|
|
|
||
|
|
def run
|
||
|
|
convert_indexes_to_i
|
||
|
|
|
||
|
|
if src_index == dst_index
|
||
|
|
return {}
|
||
|
|
end
|
||
|
|
|
||
|
|
lowest_index = src_index < dst_index ? src_index : dst_index
|
||
|
|
highest_index = src_index < dst_index ? dst_index : src_index
|
||
|
|
column_name_sanitized = ActiveRecord::Base.connection.quote_column_name(column_name)
|
||
|
|
|
||
|
|
entity_records = entity_classname.where("#{column_name_sanitized} BETWEEN #{lowest_index} AND #{highest_index}")
|
||
|
|
|
||
|
|
# reorder records
|
||
|
|
entity_records.each do |entity_record|
|
||
|
|
if entity_record.id == entity_id
|
||
|
|
entity_record[column_name] = dst_index
|
||
|
|
elsif src_index < dst_index
|
||
|
|
entity_record[column_name] -= 1
|
||
|
|
elsif src_index > dst_index
|
||
|
|
entity_record[column_name] += 1
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
# save all changes in a single transaction
|
||
|
|
entity_classname.transaction do
|
||
|
|
begin
|
||
|
|
entity_records.each(&:save!)
|
||
|
|
|
||
|
|
return entity_records
|
||
|
|
rescue
|
||
|
|
return nil
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
def convert_indexes_to_i
|
||
|
|
self.src_index = src_index.to_i
|
||
|
|
self.dst_index = dst_index.to_i
|
||
|
|
end
|
||
|
|
end
|