2012-11-26 76 views
1

在我的应用程序中,用户有重点。返回一组半最新记录

每个Highlight都有一个HighlightType。所以,如果我跑user.highlights我可能会看到这样的输出:

example of user.highlights

注意,也有TYPE_ID 47.许多亮点,这标志着用户已经运行次数的里程碑。

我想要做的是返回这个完整的记录列表,但每个highlight_type只包含一个突出显示,并且我希望这一个记录成为最近的记录(在本例中为“第50次运行”突出显示) 。所以在上面的例子中,我会得到相同的结果,但删除了ID 195-199。

有没有做到这一点的有效途径?

+0

你有没有试过'user.highlights.group('highlight_type_id')'? – MrYoshiji

+0

这似乎是“工作”,但我不确定它实际上在做什么。 GROUP不会为每个highlight_type_id返回一条记录,但我不确定它使用什么逻辑来选择特定记录。正如244an所暗示的那样,当像user.highlights.group('highlight_type_id').order('created_at DESC')这样的东西不能按预期工作时,因为排序是在分组之后完成的。如果我能理解小组选择记录背后的逻辑,那么我可以对这种方法更有信心。 – pejmanjohn

回答

1

我不认为有一个简单或干净的方法来实现这一点,也没有“Rails的方式”。看看例如这link

根据一个建议,在link你会做这样的SQL请求:

SELECT h1.* 
FROM highlights h1 
LEFT JOIN highlights h2 
ON (h1.user_id = h2.user_id 
    AND h1.highlight_type_id = h2.highlight_type_id 
    AND h1.created_at < h2.created_at) 
WHERE h2.id IS NULL AND h1.user_id = <the user id you are interested in> 
group by h1.highlight_type_id 

我认为这将是一些性能问题,如果你有大的表,也许,一个又何尝不是如此很干净,我认为。

否则,如果不是我会做这样的事情,用户这么多亮点:

rows = {} 
user.highlights.order('highlight_type_id, created_at DESC').each do |hi| 
    rows[hi.highlight_type_id] ||= hi 
end 
# then use rows which will have one object for each highlight_type_id 

上created_at的DESC是重要

编辑: 我也看到了一些建议基于此 user.highlights.group('highlight_type_id').order('created_at DESC') 这也是我第一次以为应该解决的问题,但我测试了它,似乎没有得到一个正确的结果 - 至少在我的测试数据。

+0

这里的重点。我喜欢你的第二个建议,因为它很容易理解。一个典型的用户将有50个突出记录,并且在上限处可能达到〜200条记录。任何想法,如果这可能是一个性能问题? – pejmanjohn

+0

同样对于我的特殊情况,我正在考虑在表格中添加一个标志,我在这里标记highlight_type_id的旧记录。然后我可以过滤掉这些。似乎是一个更清洁的解决方案,你呢?无论哪种方式仍然好奇,如果有一个干净,高性能的方式解决这个没有旗帜。 – pejmanjohn

+0

不知道你使用什么服务器,但我们有4年的服务器。在一些地方,我们将多达20000行数据行的结果视为没有内存问题的模型对象。对于表演,只要有几百行,我不认为你会注意到它是否只有一百个。使用标志看起来像是一个“干净的”解决方案,但这取决于该标志总是正确的。我个人会使用“哈希解决方案”。我认为“JOIN解决方案”可能会有不好的表现。 – 244an