Question

I am creating a basic forum in rails. I have a Forum that has many Threads, and the Threads have many Posts. I want to get all the Threads for a particular forum and order them in such a way that the first one is the Thread that has had the latest Post.

In my Post's repository I have a method that will return the latest post.

 def latest_post
    order('created_at DESC').limit(1).first
 end

In the Threads class I have a method call latest_post that returns the latest post

 def latest_post
    self.posts.latest_post
 end

I use that method in the following way in order to get the latest post for a thread.

@some_thread.posts.latest_post

Now I want to get the ordered list of threads. I tried to add a default scope to the Thread class in order to order them by default.

default_scope order('latest_post.created_at DESC')

This did not work. I believe due to the fact that the latest_post part of the ordering is not at a database level.

How can I order the Threads based on the creation date of their latest post. It does not need to be a default ordering.

Was it helpful?

Solution 2

Alternative answer:

I added a last_post_at column to the Thread table. When a new post is created it updates this value.

I was then able to set the default scope ordering.

 default_scope order('last_post_at DESC')

Advantage: Do not need to load all the posts when creating the ordered list of Threads for a forum. Disadvantage: Maintaining another column on the Thread model.

OTHER TIPS

Try this:

 scope :latest_post_first , Thread.joins(:posts). # joins needed to access posts for each thread
                            # grouping enables the SQL MAX function 
                            # also returns unique threads
                            group("threads.id"). 
                            # order by maximum value of post's created_at in each group 
                            # i.e. each thread since grouping is by thread id
                            order("MAX(posts.created_at) DESC") 

Note that this would only return thread's with at least one post so I do not recommend to make it the default scope.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top