38 lines
960 B
Ruby
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
|