Я предполагаю, что у вас уже есть атрибут position
для всех ваших записей. Вы должны, кстати, убедитесь, что он не может быть нулевым:
change_column :posts, :position, :integer, null: false
Скажет, у вас есть Post
, который в настоящее время является девятой должностью и должен быть пятой пост.
Прежде всего, вам необходимо временно удалить сообщение из списка позиций. Все сообщения с позиции 10 и выше необходимости убавления одно:
Post.where('position > ?', 9).update_all('position = position - 1')
Затем вам нужно поместить его обратно в список позиций. Это делается приращение всех позиций из текущей пятой позиции и далее:
Post.where('position >= ?', 5).update_all('position = position + 1')
Вся эта процедура включает в себя два запросов к базе данных, а не загружать тонны объектов ActiveRecord в память.
Вы могли бы сделать это before_update
обратного вызова, как это:
class Post
before_create :update_positions
before_update :update_positions, if: :position_changed?
def update_positions
if position_was
Post.where('position > ?', position_was).update_all('position = position - 1')
end
Post.where('position >= ?' position).update_all('position = position + 1')
end
end
Очевидный последняя часть его заказать его позиции всякий раз, когда вы показываете сообщения:
Post.all.order(:position)
'Post.order (ID:: asc) '? –
Прошу прощения, что они только закажут их по их идентификатору, мне нужно более точно контролировать позицию. –
Вы можете использовать драгоценный камень [ActsAsList] (https://github.com/swanandp/acts_as_list) для обработки процедуры обновления, не нужно изобретать колесо;) – Stefan