Rails / Postgres: столбец должен появиться в предложении GROUP BY - PullRequest
4 голосов
/ 03 августа 2011

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

Модель пользователя:

belongs_to :account

scope :have_posts, joins(:posts).where('posts.visible => true').group('users.id')

Контроллер:

@account.users.have_posts.each do |user|
  # do stuff
end

Ошибка:

(PGError: ERROR: столбец "users.account_id" должен присутствовать в предложении GROUP BY или использоваться в статистической функции: ВЫБРАТЬ "users". * ИЗ "users" INNER JOIN "posts" ON"posts". "user_id" = "users". "id" WHERE ("users" .account_id = 1) AND (examples.approved = true) GROUP BY users.id)

Жалуетсяо "users.account_id", который вызывается @account.users (поскольку я, очевидно, не хочу, чтобы все пользователи в БД).

Есть идеи, как это исправить?

Ответы [ 2 ]

6 голосов
/ 03 августа 2011

Проблема в предложении GROUP BY.Если вы используете это, вы не сможете выбрать неагрегированные поля, поэтому SELECT "users".* [...] не работает.Из документов Postgres:

В общем случае, если таблица группируется, на столбцы, которые не используются в группировке, нельзя ссылаться, кроме как в агрегированных выражениях.это может работать, хотя и беспорядочно:

scope :have_posts, 
  joins('inner join (select user_id from posts where visible = true group by user_id) users_with_posts on users_with_posts.user_id=users.id')

Одной из альтернатив будет указание каждого выбранного поля с использованием агрегатных функций, таких как MAX или MIN, но это, вероятно, сделает область еще более длинной и менее универсальной.

0 голосов
/ 16 февраля 2014

Это должно быть выражено как where условие, а не joins, потому что нет необходимости в каких-либо данных из posts. ИМХО гораздо проще читать:

scope :have_posts, -> {
  where(
    'EXISTS (SELECT 1 FROM posts p WHERE p.id = users.id AND visible = true)'
  )
}

Ruby 2 и Rails 3/4 готовы. Оптимизатор PG позаботится о том, чтобы запустить его как можно быстрее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...