# frozen_string_literal: true module Positionable extend ActiveSupport::Concern included { before_save { self.position ||= self.class.count } } def move_to(position_arg) position = [[position_arg, 0].max, self.class.count - 1].min if self.position.nil? || position > (self.position) DB.exec " UPDATE #{self.class.table_name} SET position = position - 1 WHERE position > :current_position and position <= :new_position", current_position: self.position, new_position: position elsif position < self.position DB.exec " UPDATE #{self.class.table_name} SET position = position + 1 WHERE position >= :new_position and position < :current_position", current_position: self.position, new_position: position else # Not moving to a new position return end DB.exec " UPDATE #{self.class.table_name} SET position = :position WHERE id = :id", id: id, position: position self.position = position end end