Ruby on rails 按注释排序时的范围主题查询

Ruby on rails 按注释排序时的范围主题查询,ruby-on-rails,Ruby On Rails,我试图通过最近的评论设置主题索引的顺序。这是有效的: Topic.joins(:comments).order("comments.created_at desc") 但它不止一次地列出了这些主题 有没有办法将每个主题的显示时间限制为一次?好的,情况是这样的:当您加入注释时,每个注释都会有一个数据库行,这意味着(如果一个主题上有多个注释),每个主题记录都有多个副本 要解决这个问题,您需要使用分组,这样每个主题只有一个结果。分组依据是要返回的模型的id(topics.id)。现在,还有更多的内容

我试图通过最近的评论设置主题索引的顺序。这是有效的:

Topic.joins(:comments).order("comments.created_at desc")
但它不止一次地列出了这些主题


有没有办法将每个主题的显示时间限制为一次?

好的,情况是这样的:当您加入注释时,每个注释都会有一个数据库行,这意味着(如果一个主题上有多个注释),每个主题记录都有多个副本

要解决这个问题,您需要使用分组,这样每个主题只有一个结果。分组依据是要返回的模型的id(
topics.id
)。现在,还有更多的内容-因为每个结果仍然有多个注释,每个结果也有多个created_at值,因此(为了按它排序,正如您所做的那样)您需要告诉数据库使用哪一个

这是通过某种聚合函数实现的。我猜您希望最新的注释是决定顺序的注释。如果这是真的,代码将是这样的:

Topic.joins(:comments).select('topics.*, max(comments.created_at) as last_comment').group('topics.id').order('last_comment desc')

自定义选择包括您需要的常用数据(关于主题对象的所有信息-
主题。*
)以及在注释创建日期使用的聚合函数(
max()
,顾名思义,它返回可能的最大值)。最近的日期越大,因此这将是最新评论的创建日期戳。该结果别名为
last_comment
(使用
as
),因此您可以在
.order
调用中引用该结果。

好的,发生的情况是:当您加入注释时,每个注释都会得到一个数据库行,这意味着(如果一个主题上有多个注释),每个主题记录都有多个副本

要解决这个问题,您需要使用分组,这样每个主题只有一个结果。分组依据是要返回的模型的id(
topics.id
)。现在,还有更多的内容-因为每个结果仍然有多个注释,每个结果也有多个created_at值,因此(为了按它排序,正如您所做的那样)您需要告诉数据库使用哪一个

这是通过某种聚合函数实现的。我猜您希望最新的注释是决定顺序的注释。如果这是真的,代码将是这样的:

Topic.joins(:comments).select('topics.*, max(comments.created_at) as last_comment').group('topics.id').order('last_comment desc')

自定义选择包括您需要的常用数据(关于主题对象的所有信息-
主题。*
)以及在注释创建日期使用的聚合函数(
max()
,顾名思义,它返回可能的最大值)。最近的日期越大,因此这将是最新评论的创建日期戳。该结果被化名为
last\u comment
(使用
as
),因此您可以在
.order
调用中引用它。

我发现解决此问题的最优雅方法是将
touch
添加到注释模型中的多态关联中:

属于\u to:commentable,:polymorphic=>true,touch:true

如果未使用多态关联,则可以使用:

属于\u to:topic,touch:true

然后,我所要做的就是将主题模型中的默认范围更改为
updated\u at

default\u范围顺序:“topics.updated\u at DESC”

touch
添加到注释意味着每次将注释添加到主题时,它都会更新主题中更新的_at列

在我使用的控制器中:

@topics=Topic.order(排序列+排序方向)。分页(:每页=>20,:页=>params[:页])

主题。所有
或其他内容也可以在那里工作


感谢我的超级朋友Alain向我指出了这一点。

我发现解决这个问题最优雅的方法是在注释模型中的多态关联中添加
touch

属于\u to:commentable,:polymorphic=>true,touch:true

如果未使用多态关联,则可以使用:

属于\u to:topic,touch:true

然后,我所要做的就是将主题模型中的默认范围更改为
updated\u at

default\u范围顺序:“topics.updated\u at DESC”

touch
添加到注释意味着每次将注释添加到主题时,它都会更新主题中更新的_at列

在我使用的控制器中:

@topics=Topic.order(排序列+排序方向)。分页(:每页=>20,:页=>params[:页])

主题。所有
或其他内容也可以在那里工作


感谢我的超级朋友阿兰向我指出了这一点。

如果你需要经常这样做,我会在主题模型上存储一个最后评论日期。您是否尝试添加
.group(:id)
?@MrYoshiji,它给出了一个错误
PG::error:error:column引用“id”是不明确的
@BrianMcDonough尝试
group('topics.id')
@MrYoshiji尝试了这一点,得到了这个:
PG::error:column“comments.created\u at”必须出现在GROUP BY子句中或在聚合函数行1中使用:…table_type“=“Topic”GROUP BY TOPIs.id ORDER BY comments.c..^:选择“TOPIs”。*从“TOPIs”内部连接“comments”。“commentable_id”=“TOPIs”。“id”和“comments”。“commentable_type”“='Topic'按主题分组。id按注释排序。已创建\u在desc LIMIT 20偏移量0处
如果您需要经常这样做,我会在主题模型上存储最近的注释日期。您是否尝试添加
.group(:id)
?@MrYoshiji,它给出了一个错误
PG::error:error:column引用“id”是不明确的
@BrianMcDonough尝试
group('topics.id')
@MrYoshiji尝试了一下,得到了这个:
PG::error