views:

1347

answers:

3

This seems like a really simple question but I haven't seen it answered anywhere.

In rails if you have:

class Article < ActiveRecord::Base 
  has_many :comments 
end 
class Comments < ActiveRecord::Base 
  belongs_to :article 
end

Why can't you order the comments with something like this:

@article.comments(:order=>"created_at DESC")

Named scope works if you need to reference it a lot and even people do stuff like this:

@article.comments.sort { |x,y| x.created_at <=> y.created_at }

But something tells me it should be simpler. What am I missing?

+3  A: 

You can use ActiveRecord's find method to get your objects and sort them too.

  @article.comments.find(:all, :order => "created_at DESC")

http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html

vrish88
Or the shorthand method @article.comments.all(:order => 'created_at DESC')
erik
+12  A: 

You can specify the sort order for the bare collection with an option on has_many itself:

class Article < ActiveRecord::Base 
  has_many :comments, :order => 'created_at DESC'
end 
class Comment < ActiveRecord::Base 
  belongs_to :article 
end

Or, if you want a simple, non-database method of sorting, use sort_by:

article.comments.sort_by &:created_at

Collecting this with the ActiveRecord-added methods of ordering:

article.comments.find(:all, :order => 'created_at DESC')
article.comments.all(:order => 'created_at DESC')

Your mileage may vary: the performance characteristics of the above solutions will change wildly depending on how you're fetching data in the first place and which Ruby you're using to run your app.

Jim Puls
Thanks, the "all" is probably the simplest. Good stuff!
Brian Armstrong
+1  A: 

If you are using Rails 2.3 and want to use the same default ordering for all collections of this object you can use default_scope to order your collection.

class Student < ActiveRecord::Base
  belongs_to :class

  default_scope :order => 'name'

end

Then if you call

@students = @class.students

They will be ordered as per your default_scope. TBH in a very general sense ordering is the only really good use of default scopes.

railsninja