module Positionable extend ActiveSupport::Concern def move_to(position_arg) position = [[position_arg, 0].max, self.class.count - 1].min if self.position.nil? or position > self.position self.exec_sql " 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 self.exec_sql " 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 self.exec_sql " UPDATE #{self.class.table_name} SET position = :position WHERE id = :id", {id: id, position: position} end def use_default_position self.exec_sql " UPDATE #{self.class.table_name} SET POSITION = null WHERE id = :id", {id: id} end end