Rails 3, ActiveRecord, PostgreSQL - команда ".uniq" не работает?

У меня есть следующий запрос:

Article.joins(:themes => [:users]).where(["articles.user_id != ?", current_user.id]).order("Random()").limit(15).uniq

и дает мне ошибку

PG::Error: ERROR:  for SELECT DISTINCT, ORDER BY expressions must appear in select list
LINE 1: ...s"."user_id" WHERE (articles.user_id != 1) ORDER BY Random() L...

Когда я обновляю исходный запрос до

Article.joins(:themes => [:users]).where(["articles.user_id != ?", current_user.id]).order("Random()").limit(15)#.uniq

поэтому ошибка исчезла... В MySQL .uniq работает, в PostgreSQL нет. Существуют ли какие-либо альтернативы?

Ответы

Ответ 1

По мере возникновения ошибки for SELECT DISTINCT, ORDER BY expressions must appear in select list. Поэтому вы должны явно выбрать для заказа, который вы заказываете.

Вот пример, он похож на ваш случай, но немного обобщает.

Article.select('articles.*, RANDOM()')
       .joins(:users)
       .where(:column => 'whatever')
       .order('Random()')
       .uniq
       .limit(15)

Итак, явным образом включите предложение ORDER BY (в данном случае RANDOM()) с помощью .select(). Как показано выше, чтобы ваш запрос возвращал атрибуты статьи, вы также должны явно выбирать их.

Я надеюсь, что это поможет; удачи

Ответ 2

Просто чтобы обогатить поток большим количеством примеров, в случае, если у вас есть вложенные отношения в запросе, вы можете попробовать следующее утверждение.

Person.find(params[:id]).cars.select('cars.*, lower(cars.name)').order("lower(cars.name) ASC")

В данном примере вы спрашиваете все автомобили для данного человека, заказанные по названию модели (Audi, Ferrari, Porsche)

Я не думаю, что это лучший способ, но может помочь решить подобную ситуацию мышления в объектах и ​​коллекциях вместо реляционного (базы данных).

Спасибо!

Ответ 3

Я предполагаю, что метод .uniq переведен в предложение DISTINCT на SQL. PostgreSQL является придирчивым (pickier, чем MySQL) - все поля в списке выбора при использовании DISTINCT должны присутствовать в предложениях ORDER_BYGROUP_BY).

Немного непонятно, что вы пытаетесь сделать (случайный порядок?). В дополнение к отправке полного отправленного SQL, если вы могли бы объяснить свою цель, это могло бы помочь найти альтернативу.

Ответ 4

Я только что обновил свое 100% работающее и протестированное приложение от 3.1.1 до 3.2.7 и теперь имею эту же PG:: Error.

Я использую Cancan...

@users = User.accessible_by (current_ability).order('lname asc'). uniq

Удаление .uniq решает проблему, и в любом случае это не было необходимо для этого простого запроса.

Просматривая примечания об изменениях между 3.1.1 и 3.2.7, чтобы увидеть, что заставило это сломаться.