ActiveRecord 4.2包括按计数排序

时间:2016-02-16 07:43:30

标签: ruby-on-rails ruby postgresql activerecord

我正在寻找我正在研究的项目。它旨在能够搜索文章正文并制作一份作者列表,按照匹配文章的数量排序,仅包括相关文章,而不是所有文章。

我目前有以下查询:

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

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(实质上,文章只由一位作者撰写)。改为外键是什么。

因此,根据他们撰写的文章数量,您将拥有一系列作者。