简体   繁体   English

Ruby on Rails按子属性命令父模型

[英]Ruby on Rails order a parent model by child attribute

How would I go about doing this? 我该怎么做呢? I would like to sort a selection parent model by an attribute on it's children. 我想通过它的子项上的属性对选择父模型进行排序。 The parent model has a has many relationship with it's child. 父模型与它的孩子有很多关系。 I'm not sure how to form the ActiveRecord query to get this. 我不确定如何形成ActiveRecord查询来获取此信息。

Example: A thread has many posts. 示例:一个帖子有很多帖子。 I want to grab a collection of threads ordered by the most recent post associated with it. 我想获取与其相关的最新帖子所订购的线程集合。

I've found a few solutions that convert the selection to an array and do a sort on that array, but I need the selection to stay as an ActiveRecord selection, so I can continue to chain queries onto it. 我找到了一些解决方案,将选择转换为数组并对该数组进行排序,但我需要选择保留为ActiveRecord选择,因此我可以继续将查询链接到它上面。

我需要有关数据库布局的更多信息以提供更好的示例,但您可以加入另一个表,然后按该表排序,如下所示:

Thread.joins(:posts).order("posts.created_at").group("threads.id")

For your example, it would be far more efficient to simply have the children touch the parent: 举个例子,简单地让孩子接触父母会更有效率:

class Thread < ActiveRecord::Base
  has_many :posts
end

class Post < ActiveRecord::Base
  belongs_to :thread,
        touch: true
end

This will change Thread's updated_at column whenever a post is created or changed, so that thread is considered updated at that time. 每当创建或更改帖子时,这将更改Thread的updated_at列,以便在那时认为该线程已更新。 You may need to actually access the child records in a more complicated example, but for ordering by the date of the child posts this saves you having to get the extra records out of the database when you don't actually need information from that table. 您可能需要在更复杂的示例中实际访问子记录,但是为了按子帖的日期排序,这样可以节省您在实际上不需要该表中的信息时从数据库中获取额外记录的情况。

By using just plain queries, with no direct iteration over arrays, you can do something like: 通过使用普通查询,没有直接迭代数组,您可以执行以下操作:

Post.joins(:thread).includes(:thread).order("posts.created_at").group("thread_id").take(5) 
# Maybe you can take only a few samples of your collection to show on Last Posted Topics, 
# then you just replace take(5) with the number of posts you want to take.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM