我有一个Post模型。
我想在“邮寄”的基础上详细说明他们的订单。
我认为position:integer属性是一个好的开始。
这是一个使用Post.order(position: :asc)呈现的示例:

id: 3, position: 1
id: 2, position: 2
id: 8, position: 3
...

但更新过程会如何进行呢或者其他更好的主意?

最佳答案

我假设您已经为所有记录设置了position属性。顺便说一句,你应该确保它不能为零:

change_column :posts, :position, :integer, null: false

假设你有一个Post现在是第9个职位,需要是第5个职位。
首先,你需要从职位列表中临时“删除”职位所有职位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)

关于ruby-on-rails - 给每个Post实例一个自定义订单位置,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21072927/

10-12 12:33
查看更多