# Sorting By Last Comment? ("post.comments.first.created\_on")

**URL:** <https://www.ruby-forum.com/t/sorting-by-last-comment-post-comments-first-created-on/109465>\
**Category:** Rails\
**Created:** [July 15, 2007, 12:55pm UTC](https://www.ruby-forum.com/t/sorting-by-last-comment-post-comments-first-created-on/109465 "2007-07-15T12:55:42Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![adistarmid](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/f14d63/32.png) [@adistarmid](https://www.ruby-forum.com/u/adistarmid)\
**Post date:** [July 15, 2007, 12:55pm UTC](https://www.ruby-forum.com/t/sorting-by-last-comment-post-comments-first-created-on/109465/1 "2007-07-15T12:55:42Z")

</div>

I’m trying to order a table based on the last comment, and have tried  
almost everything and still can’t get it working.

My specs are just like the API’s  
([ActiveRecord::Associations::ClassMethods](http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#M000644))

`
class Post < ActiveRecord::Base
belongs_to :author
has_many :comments
end
Consider the following loop using the class above:
for post in Post.find(:all)
puts "Post: " + post.title
puts "Written by: " + post.author.name
puts "Last comment on: " + post.comments.first.created_on
end
`

I tried doing:

“:order =\> ‘@posts.comments.first.created\_on DESC’” – but can’t get it  
working.

How could I order the table based on “post.comments.first.created\_on”?

---

<div class="post-metadata">

**Author:** ![adistarmid](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/f14d63/32.png) [@adistarmid](https://www.ruby-forum.com/u/adistarmid)\
**Post date:** [July 15, 2007, 6:00pm UTC](https://www.ruby-forum.com/t/sorting-by-last-comment-post-comments-first-created-on/109465/2 "2007-07-15T18:00:34Z")

</div>

Aah,  
it appears you misunderstand how the :order key works in a find,  
it’s all a question of SQL.

Firstly,  
you want to make your code efficient,  
so you want to achieve your outcome in as few DB queries as possible.

For every has\_many, or belongs\_to, it needs to make a database query,  
so instead, we’ll “eager” load these when we do our find.

all\_with\_attributes = Post.find(:all, :include =\> [:author, :comments]

but, actually, we don’t need this,  
if you’re not using the comments, and only the time of the comment,  
instead we’ll define a “last\_comment” in your class

class Post \< ActiveRecord::Base  
belongs\_to :author  
has\_many :comments  
has\_one :last\_comment,  
:class\_name =\> “Comment”,  
:order =\> “comments.created\_at DESC”  
end

This now let’s your write @post.last\_comment.created\_at

so, now our find should be;

Post.find(:all,  
:include =\> [:author, :last\_comment],  
:order =\> “comments.created\_at DESC”  
)

And I think we’ll have what you need.

If that’s too confusing for you,  
you can just do the following in ruby (rather than in the db)

Post.find(:all,  
:include =\> [:author, :comments]  
).sort\_by{|p| p.comments.last.created\_at}

- the include is optional, but seriously, you need to be doing this
- watch your development.log when you don’t

or

Post.find(:all,  
:include =\> [:author, :comments],  
:order =\> “comments.created\_at DESC”  
)

would probably work too.

Bob S. wrote:

> I’m trying to order a table based on the last comment, and have tried  
> almost everything and still can’t get it working.
> 
> class Post \< ActiveRecord::Base  
> belongs\_to :author  
> has\_many :comments  
> end
> 
> Consider the following loop using the class above:
> 
> for post in Post.find(:all)  
> puts "Post: " + post.title  
> puts "Written by: " + post.author.name  
> puts "Last comment on: " + post.comments.first.created\_on  
> end

---

<div class="post-metadata">

**Author:** ![adistarmid](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/f14d63/32.png) [@adistarmid](https://www.ruby-forum.com/u/adistarmid)\
**Post date:** [July 16, 2007, 3:06am UTC](https://www.ruby-forum.com/t/sorting-by-last-comment-post-comments-first-created-on/109465/3 "2007-07-16T03:06:46Z")

</div>

Matthew! You’re awesome! Thank you so much for your informative post. I  
can’t tell you how appreciative I am. Thank you, thank you, thank you 🙂

I tried the first method, and it works great. I had issue with  
displaying the latest date, so I used your second approach,  
specifically:

Post.find(:all,  
:include =\> [:author, :comments],  
:order =\> “comments.created\_at DESC”  
)

Then in the view, I incorporated this: post.comments.first.created\_at,  
and it works perfectly like how I wanted.

Thank you so much for your help, Matthew!!

Matthew R. wrote:

> Aah,  
> it appears you misunderstand how the :order key works in a find,  
> it’s all a question of SQL.
> 
> Firstly,  
> you want to make your code efficient,  
> so you want to achieve your outcome in as few DB queries as possible.
> 
> For every has\_many, or belongs\_to, it needs to make a database query,  
> so instead, we’ll “eager” load these when we do our find.
> 
> all\_with\_attributes = Post.find(:all, :include =\> [:author, :comments]
> 
> but, actually, we don’t need this,  
> if you’re not using the comments, and only the time of the comment,  
> instead we’ll define a “last\_comment” in your class
> 
> class Post \< ActiveRecord::Base  
> belongs\_to :author  
> has\_many :comments  
> has\_one :last\_comment,  
> :class\_name =\> “Comment”,  
> :order =\> “comments.created\_at DESC”  
> end
> 
> This now let’s your write @post.last\_comment.created\_at
> 
> so, now our find should be;
> 
> Post.find(:all,  
> :include =\> [:author, :last\_comment],  
> :order =\> “comments.created\_at DESC”  
> )
> 
> And I think we’ll have what you need.
> 
> If that’s too confusing for you,  
> you can just do the following in ruby (rather than in the db)
> 
> Post.find(:all,  
> :include =\> [:author, :comments]  
> ).sort\_by{|p| p.comments.last.created\_at}
> 
> - the include is optional, but seriously, you need to be doing this
> - watch your development.log when you don’t
> 
> or
> 
> Post.find(:all,  
> :include =\> [:author, :comments],  
> :order =\> “comments.created\_at DESC”  
> )
> 
> would probably work too.
> 
> Bob S. wrote:
> 
> > I’m trying to order a table based on the last comment, and have tried  
> > almost everything and still can’t get it working.
> > 
> > class Post \< ActiveRecord::Base  
> > belongs\_to :author  
> > has\_many :comments  
> > end
> > 
> > Consider the following loop using the class above:
> > 
> > for post in Post.find(:all)  
> > puts "Post: " + post.title  
> > puts "Written by: " + post.author.name  
> > puts "Last comment on: " + post.comments.first.created\_on  
> > end

---

<div class="post-metadata">

**Author:** ![adistarmid](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/f14d63/32.png) [@adistarmid](https://www.ruby-forum.com/u/adistarmid)\
**Post date:** [July 16, 2007, 2:51pm UTC](https://www.ruby-forum.com/t/sorting-by-last-comment-post-comments-first-created-on/109465/4 "2007-07-16T14:51:17Z")

</div>

Why are you doing comments.first? You’ll only ever get the most recent  
comment if there’s only one there.

post.comments.find(:first, :order =\> “created\_on DESC”).created\_on

should get you what you need.

Also, just so you know, the Ruby Way of your code is as follows:

Post.find(:all).each do |post|  
…  
end

Jason
