Rails ActiveRecord模型中的Model.uniq.pluck :id在Postgres上无法工作。

4
我有一个空的Rails 4 应用程序,尝试执行以下操作:Collection.order('created_at ASC').uniq.pluck :name 它在sqlite下可以正常工作,但在postgres中会出现以下错误:
(0.9ms)  SELECT DISTINCT "collections"."name" FROM "collections" ORDER BY created_at ASC
PG::Error: ERROR:  for SELECT DISTINCT, ORDER BY expressions must appear in select list
LINE 1: ...collections"."name" FROM "collections"   ORDER BY created_at...

这是一个Bug吗?还是有什么方法可以修复它?


也许更清晰的用例是使用:name或任何其他属性。这就是我想要实现的。谢谢。 - randomor
不是排序引起了你的问题,而是uniq。为什么要使用它?你能否移除它? - Jesse Wolgamott
@JesseWolgamott 为什么 #uniq 会引起问题?我也尝试了 Rails3。看起来只有在与 order 一起使用时,uniq 才会成为问题。最终我没有使用 order。但是这种行为仍然让我感到困惑,因为在 sqlite 中它显然可以工作。 - randomor
好的——你可以打开一个Rails问题,或者删除uniq,因为它似乎没有起到任何作用。 - Jesse Wolgamott
3个回答

2

这似乎是PostgreSQL的问题。(Rails 3 DISTINCT QUERY

要解决这个问题,您可以使用select代替:

Collection.select([:name, :created_at]).order('created_at ASC').uniq.select(:name)

或者您可以让Ruby获取唯一的名称而不是SQL:

Collection.order('created_at ASC').pluck(:name).uniq


谢谢。你的第一个解决方案在Rails 4下仍然不起作用:Collection.select([:name, :created_at]).order('created_at ASC').uniq.pluck(:name)但我认为第二个解决方案可以工作。只是不确定性能影响,我不太担心。ActiveRecord中的#pluck方法似乎是罪魁祸首。自Rails4以来它也发生了很多变化。谢谢! - randomor

2

我实际上正在尝试解决active_admin的这个问题。https://github.com/gregbell/active_admin/issues/2324

现在的解决方案似乎是Collection.reorder('name asc').uniq.pluck :name,这将覆盖默认范围或先前的顺序,并按name对集合进行排序。奇怪的是,reorder可以正常工作,而order会导致问题...


1
Collection.select([:id, :created_at]).order('created_at ASC').uniq.pluck(:id)

谢谢。但是它不起作用。PG :: Error:ERROR:对于SELECT DISTINCT,ORDER BY表达式必须出现在选择列表中 LINE 1:...“collections”。“id”FROM“collections”ORDER BY created_at ... ^ :SELECT DISTINCT“collections”。“id”FROM“collections”ORDER BY created_at ASC ActiveRecord :: StatementInvalid:PG :: Error:ERROR:对于SELECT DISTINCT,ORDER BY表达式必须出现在选择列表中 LINE 1:...“collections”。“id”FROM“collections”ORDER BY created_at - randomor
我在Rails 3.2上进行了测试,也许'select'方法已经改变了,请尝试使用:select("id, created_at")。 - cthulhu
你也在使用Postgres吗?出现了同样的错误。实际上,只使用Collection.order('created_at ASC').uniq就可以工作了,但是一旦我开始使用pluck,它就会崩溃。不过在SQLite中可以正常工作 :(. - randomor
是的,我正在使用Postgres进行测试。生成的SQL语句是:SELECT DISTINCT id, created_at, id FROM "users" ORDER BY created_at ASC - cthulhu
我在另一个Rails3控制台上进行了测试,你的方法确实有效!但不幸的是,在Rails4上它不知何故不起作用... - randomor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接