Rails ActiveRecord Model.uniq.pluck:id не работает с postgres

У меня есть пустое демонстрационное приложение для рельсов 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...

Это ошибка или как я могу это исправить?


person randomor    schedule 05.07.2013    source источник
comment
Возможно, более понятным вариантом использования является использование :name или любых других атрибутов. Вот чего я хотел добиться. Спасибо.   -  person randomor    schedule 05.07.2013
comment
Это не порядок, который вызывает ваши проблемы, это uniq. Почему он у вас есть? можешь удалить?   -  person Jesse Wolgamott    schedule 05.07.2013
comment
@JesseWolgamott Почему #uniq вызывает проблему? Я также пробовал rails3. Похоже, что uniq является проблемой только при использовании с order. В итоге я не использовал order. Но все еще озадачен таким поведением, потому что оно, очевидно, работает в sqlite.   -  person randomor    schedule 05.07.2013
comment
Что ж, вы можете открыть проблему с рельсами или удалить uniq, который, похоже, ничего не делает.   -  person Jesse Wolgamott    schedule 06.07.2013


Ответы (3)


Кажется, это проблема с 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

person varatis    schedule 05.07.2013
comment
Спасибо. Ваше первое решение все еще не работает под рельсами 4: Collection.select([:name, :created_at]).order('created_at ASC').uniq.pluck(:name) Но я думаю, что второе работает. Просто не уверен насчет влияния на производительность, о чем я не слишком беспокоюсь. Метод #pluck в ActiveRecord выглядит виновным. Он также сильно изменился со времен rails4. Спасибо! - person randomor; 05.07.2013

На самом деле я пытался решить эту проблему на active_admin. https://github.com/gregbell/active_admin/issues/2324

Теперь решение кажется Collection.reorder('name asc').uniq.pluck :name, это перезапишет default_scope или предыдущий порядок и закажет коллекции с name. Странно то, что reorder работает, а order вызывает проблему...

person randomor    schedule 05.07.2013

person    schedule
comment
Спасибо. Но это не работает. PG::Error: ERROR: for SELECT DISTINCT, ORDER BY expressions must appear in select list 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: for SELECT DISTINCT, ORDER BY expressions must appear in select list LINE 1: ... "collections"."id" FROM "collections" ORDER BY created_at - person randomor; 05.07.2013
comment
Я тестировал его на rails 3.2, возможно, метод select был изменен, попробуйте: select(id, created_at) - person cthulhu; 05.07.2013
comment
Вы тоже используете постгрес? Та же ошибка. На самом деле он работает только с Collection.order('created_at ASC').uniq, как только я начал с pluck, он взрывается. Однако он работает с sqlite :(. - person randomor; 05.07.2013
comment
Да, я тестирую его на postgres. Сгенерированный SQL: SELECT DISTINCT id, created_at, id FROM "users" ORDER BY created_at ASC - person cthulhu; 05.07.2013
comment
Я проверил на другой консоли rails3, и ваш метод действительно работает! Но, к сожалению, это почему-то не работает на rails4... - person randomor; 05.07.2013