2014-04-19 12:00:40 +08:00
|
|
|
module Positionable
|
|
|
|
extend ActiveSupport::Concern
|
|
|
|
|
2014-05-16 23:33:44 +08:00
|
|
|
included do
|
|
|
|
before_save do
|
|
|
|
self.position ||= self.class.count
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-04-19 12:00:40 +08:00
|
|
|
def move_to(position_arg)
|
|
|
|
|
|
|
|
position = [[position_arg, 0].max, self.class.count - 1].min
|
|
|
|
|
2017-07-28 09:20:09 +08:00
|
|
|
if self.position.nil? || position > (self.position)
|
2018-06-19 14:13:14 +08:00
|
|
|
DB.exec "
|
2014-04-19 12:00:40 +08:00
|
|
|
UPDATE #{self.class.table_name}
|
|
|
|
SET position = position - 1
|
|
|
|
WHERE position > :current_position and position <= :new_position",
|
2017-07-28 09:20:09 +08:00
|
|
|
current_position: self.position, new_position: position
|
2014-04-19 12:00:40 +08:00
|
|
|
elsif position < self.position
|
2018-06-19 14:13:14 +08:00
|
|
|
DB.exec "
|
2014-04-19 12:00:40 +08:00
|
|
|
UPDATE #{self.class.table_name}
|
|
|
|
SET position = position + 1
|
|
|
|
WHERE position >= :new_position and position < :current_position",
|
2017-07-28 09:20:09 +08:00
|
|
|
current_position: self.position, new_position: position
|
2014-04-19 12:00:40 +08:00
|
|
|
else
|
|
|
|
# Not moving to a new position
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
2018-06-19 14:13:14 +08:00
|
|
|
DB.exec "
|
2014-04-19 12:00:40 +08:00
|
|
|
UPDATE #{self.class.table_name}
|
|
|
|
SET position = :position
|
2017-07-28 09:20:09 +08:00
|
|
|
WHERE id = :id", id: id, position: position
|
2014-04-19 12:00:40 +08:00
|
|
|
end
|
|
|
|
end
|