2012-01-07 60 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這樣的插件,它提供了這個和其他有用的功能。