1

My Thread model has many Posts. Let's say I want to reorder posts by an array containg ids I wish to see my posts sorted by.

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]

What am I doing wrong? Is sorting by id always preserved in collections and can I somehow disable it?

1 Answer 1

2

You should always assume the order of results retrieved from your database as being more or less "random", unless you specifically ask it to sort them. This means that you can not rely on your database to magically store the order of posts associated with a thread (in fact, the code sample you posted would probably not query the database at all, because there is nothing to update).

The easiest way to achieve what you want is to add an order field to your Post model like this:

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

In your Thread model:

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

Afterwards you will be able to reorder the posts like this:

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

If you want, you can also use a plugin like acts_as_list which provides this and other useful functionality.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.