我正在学习rails并且一直在尝试阅读文档,但我还是不知道如何#group 的工作原理。
文档说它:"根据组属性"返回一个具有不同记录的数组。
然后如何检索属于某个群组的记录?
说我想按照创建它们的月份对Articles
进行分组?我该怎么办?
答案 0 :(得分:3)
group
方法通常与select
方法一起使用来进行聚合查询。例如,如果您希望按月计算您的文章,则可以执行以下操作:
by_month = Article.group(:month).select("month", "COUNT(*) as count")
在这种情况下,COUNT
是计算行数的SQL聚合函数,我们将计数结果放入名为" count"的输出列中。
注意:这假设您有一个名为" month"的列。当然你可以在这里做SQL,所以你可能会这样做,例如MONTH(created_at)
代替,或者在你的情况下有意义。
然后,您可以执行此操作以输出月份及其相关的文章计数:
by_month.each do |row|
puts "Month #{row.month}: #{row.count}"
end
这可能看起来很神秘,因为你的模型没有列"计数",但这就是select
的工作方式:它为动态查询定义新的输出列,以及ActiveRecord在生成的实例对象中愉快地映射了那些。
这种查询比加载所有记录并自己计算更有效率,因为您让数据库执行繁重的数据工作,以及它擅长的是什么。
在没有group
的情况下使用select
是完全合法的,但结果通常不是您想要的。如果按月对文章进行分组,则每个月都会在结果中获得一个对象。每个对象中可用的列因数据库后端而异,但在MySQL中,它们将具有来自" first"每个组遇到的行。如果你没有排序,首先"基本上是未定义的。
如果按照"分组文章创建它们的月份"你的意思是你想在网页结果上进行这种分组,那么你必须自己做,例如:
<% last_month = nil %>
<% @articles.each do |article| %>
<% if last_month != article.month %>
<h2><%= article.month %></h2>
<% last_month = article.month %>
<% end %>
# [output the article]
<% end %>
如果您执行此类操作,则需要确保按月排序@articles
。