2012-01-07 50 views
1

我的Thread模型有很多Posts。比方说,我想通过一个包含ID的数组重新排列帖子,我希望看到我的帖子按排序。排序收集来自阵列的ID

thread.posts.collect {|x| x.id} # => [1,2,3] 
order = [2,3,1] 

posts = thread.posts.sort_by {|x| order.index x.id} 
posts.collect {|x| x.id} # => [2,3,1] 

thread.update_attributes(:posts => posts) # => true 
thread.posts.collect {|x| x.id} # => [1,2,3] 

我在做什么错?按id排序总是保存在集合中,我可以以某种方式禁用它吗?

回答

2

您应该始终假定从数据库中检索到的结果顺序或多或少是“随机的”,除非您专门要求将其排序。这意味着你可以而不是依靠你的数据库神奇地存储与一个线程相关的帖子的顺序(实际上,你发布的代码样本可能根本不会查询数据库,因为没有什么需要更新)。

达到你想要的最简单的方法是将order字段添加到您的Post模式是这样的:

class AddOrderToPost < ActiveRecord::Migration 
    def up 
    change_table :posts do |t| 
     t.integer :order, :default => 0 
    end 
    Post.update_all ["order = ?", 0] 
    end 

    def down 
    remove_column :posts, :order 
    end 
end 

在你Thread型号:

class Thread < ActiveRecord::Base 
    # ... 
    has_many :posts, :order => 'order ASC' 
    # ... 
end 

之后,你就可以重新排列这样的帖子:

thread.posts.zip([2,3,1]) { |p,i| p.order = i } 

如果你愿意,你也可以使用像acts_as_list这样的插件,它提供了这个和其他有用的功能。