discourse/lib/concern/positionable.rb

38 lines
960 B
Ruby

module Concern
module Positionable
extend ActiveSupport::Concern
included do
before_save do
self.position ||= self.class.count
end
end
def move_to(position)
self.exec_sql "
UPDATE #{self.class.table_name}
SET position = position - 1
WHERE position > :position AND position > 0", {position: self.position}
self.exec_sql "
UPDATE #{self.class.table_name}
SET position = :position
WHERE id = :id", {id: id, position: position}
self.exec_sql "
UPDATE #{self.class.table_name} t
SET position = x.position - 1
FROM (
SELECT i.id, row_number()
OVER(ORDER BY i.position asc,
CASE WHEN i.id = :id THEN 0 ELSE 1 END ASC) AS position
FROM #{self.class.table_name} i
WHERE i.position IS NOT NULL
) x
WHERE x.id = t.id AND t.position <> x.position - 1
", {id: id}
end
end
end