什么是有效抓取父表的所有行的“轨道方式”以及每行的子节点数?
我不想使用counter_cache
,因为我想根据某些时间条件运行这些计数。
陈词滥调的博客示例:文章表。每篇文章都有0条或更多条评论。
我希望能够提取每篇文章在过去一小时,一天,一周中有多少评论。
但是,理想情况下,我不想迭代列表并为每篇文章单独调用sql,我也不想使用:include
预取所有数据并在应用服务器上处理它。
我想运行一个SQL语句并获得一个包含所有信息的结果集。
我知道我可以硬编码完整的SQL,也许可以使用.find
并设置:joins
,:group
和:conditions
参数...但我想知道是否有“更好”的方式...又名“轨道办法”
提前致谢
这个activerecord调用应该做你想要的:
Article.find(:all, :select => 'articles.*, count(posts.id) as post_count',
:joins => 'left outer join posts on posts.article_id = articles.id',
:group => 'articles.id'
)
这将返回一个文章对象列表,每个文章对象都有方法post_count
,其中包含文章中作为字符串的帖子数。
该方法执行类似于以下的sql:
SELECT articles.*, count(posts.id) AS post_count
FROM `articles`
LEFT OUTER JOIN posts ON posts.article_id = articles.id
GROUP BY articles.id
如果您很好奇,这是您在运行此类查询时可能会看到的MySQL结果的示例:
+----+----------------+------------+
| id | text | post_count |
+----+----------------+------------+
| 1 | TEXT TEXT TEXT | 1 |
| 2 | TEXT TEXT TEXT | 3 |
| 3 | TEXT TEXT TEXT | 0 |
+----+----------------+------------+
对于Rails 3,你会看到这样的东西:
Article.select( "articles.*, count(comments.id) AS comments_count" )
.joins( "LEFT OUTER JOIN comments ON comments.article_id = articles.id" )
.group( "articles.id" )
感谢Gdeglin的Rails 2版本。
我用来解决这个问题的一个简单方法是
在我的模型中,我做了:
class Article < ActiveRecord::Base
has_many :posts
def count_posts
Post.where(:article_id => self.id).count
end
end
现在,您可以使用例如:
Articles.first.count_posts
我不确定它是否可以更有效,但它是一个解决方案,在我看来比其他更优雅。
从SQL的角度来看,这看起来微不足道 - 只需编写一个新查询。
从Rails的角度来看,您提到的值是计算值。因此,如果使用find_by_sql
,Model类将不知道计算字段,因此即使您设法将查询转换为Rails发言,也会将计算值作为字符串返回。请参阅下面的链接问题
一般的漂移(从我得到的问题的答案)是有一个单独的类负责汇总/计算所需的值。
How to get rails to return SUM(columnName) attributes with right datatype instead of a string?
我用这种方式做了这个工作:
def show
section = Section.find(params[:id])
students = Student.where( :section_id => section.id ).count
render json: {status: 'SUCCESS', section: students},status: :ok
end
在这我有2个模型科和学生。所以我必须计算匹配特定id部分的学生人数。