【问题标题】:Sort objects based on the creation date of their children根据子对象的创建日期对对象进行排序
【发布时间】:2013-10-16 09:14:02
【问题描述】:

我在 Rails 中创建一个基本论坛。我有一个有很多主题的论坛,并且主题有很多帖子。我想获取特定论坛的所有主题,并以第一个是拥有最新帖子的主题的方式对它们进行排序。

在我的帖子存储库中,我有一个可以返回最新帖子的方法。

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

在 Threads 类中,我有一个方法调用 latest_post,它返回最新的帖子

 def latest_post
    self.posts.latest_post
 end

我以以下方式使用该方法来获取线程的最新帖子。

@some_thread.posts.latest_post

现在我想获取线程的有序列表。我尝试为 Thread 类添加一个默认范围,以便默认对其进行排序。

default_scope order('latest_post.created_at DESC')

这不起作用。我相信由于排序的 latest_post 部分不在数据库级别。

如何根据最新帖子的创建日期对主题进行排序。它不需要是默认排序。

【问题讨论】:

    标签: ruby-on-rails ruby activerecord forum


    【解决方案1】:

    试试这个:

     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") 
    

    请注意,这只会返回至少有一篇帖子的线程,所以我不建议将其设为默认范围。

    【讨论】:

    • 感谢您的回复。正是我正在寻找的解决方案。我唯一关心的是效率。如果线程有很多帖子,这种方法会开始降低速度吗?
    • sql 内部连接会因需要检索的帖子行数而减慢,在这种情况下,缓存或其他列是更好的选择。
    【解决方案2】:

    另一种答案:

    我在 Thread 表中添加了 last_post_at 列。创建新帖子时,它会更新此值。

    然后我可以设置默认范围排序。

     default_scope order('last_post_at DESC')
    

    优点:在为论坛创建主题的有序列表时不需要加载所有帖子。 缺点:在 Thread 模型上维护另一个列。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-24
      • 1970-01-01
      • 1970-01-01
      • 2018-03-04
      • 1970-01-01
      相关资源
      最近更新 更多