我正在寻找我正在研究的项目。它旨在能够搜索文章正文并制作一份作者列表,按照匹配文章的数量排序,仅包括相关文章,而不是所有文章。
我目前有以下查询:
Author.includes(:articles).where('articles.body ilike ?', '%foo%').references(:articles)
在这种情况下使用包含使得所有相关文章(不是所有文章)都被预加载,这正是我想要的。但是,当按照所包含文章的数量进行排序时,我不确定如何继续。
我应该注意我想在ActiveRecord中执行此操作,因为在查询之后将应用分页。不是在Ruby解决方案之后。
我应该注意到我正在使用PostgreSQL 9.3。
编辑:使用原始SQL
这似乎就像它自己一样:
Author.includes(:articles).where('articles.body ilike ?', '%foo%').references(:articles).select('authors.*, (SELECT COUNT(0) FROM articles WHERE articles.author_id = authors.id) AS article_count').order('article_count DESC')
这很好用。但是,如果我添加.limit(1)
,它就会中断。
PG::UndefinedColumn: ERROR: column "article_count" does not exist
知道为什么添加限制会破坏它吗?查询似乎也非常不同
SELECT DISTINCT "authors"."id", article_count AS alias_0 FROM "authors" LEFT OUTER JOIN "articles" ON "articles"."author_id" = "authors"."id" WHERE (articles.body ilike '%microsoft%') ORDER BY article_count DESC LIMIT 1
答案 0 :(得分:1)
我认为没有开箱即用的解决方案。您必须编写原始sql才能执行此操作,但您可以将其与现有的ActiveRecord
查询结合使用。
Author
.includes(:articles)
.select('authors.*, (SELECT COUNT(0) FROM articles WHERE articles.author_id = authors.id) AS article_count')
.order('article_count DESC')
所以这里唯一需要解释的是select
部分。第一部分authors.*
选择authors表下的所有字段,这是默认值。由于我们还想计算文章的数量,我们创建一个子查询并将其结果作为作者的伪列之一传递(我们称之为article_count
)。最后一部分是使用order
调用article_count
。
此解决方案假设您需要根据您的设置进行微调。
Author
按惯例在rails中映射到authors表。如果它是STI(继承自User
类并且正在使用用户表),则您需要将authors
更改为users
。articles.author_id
假设外键是author_id
(实质上,文章只由一位作者撰写)。改为外键是什么。因此,根据他们撰写的文章数量,您将拥有一系列作者。