Rails 3 ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ
У вас есть таблица User, UserBadge и Badge. Они связаны через has_many через. Пользователь может иметь несколько одинаковых значков, но я хочу запросить уникальный список.
@user.badges.select("DISTINCT id").order("created_at DESC")
Это ошибка:
SQLite3::SQLException: near "DISTINCT": syntax error:
Каким будет правильный синтаксис?
ИЗМЕНИТЬ: ДОБАВЛЯЕТСЯ ВЕСЬ ОШИБКА
SQLite3::SQLException: near "DISTINCT": syntax error: SELECT "badges".*, DISTINCT badges.id FROM "badges" INNER JOIN "userbadges" ON "badges".id = "userbadges".badges_id WHERE (("userbadges".user_id = 1))
Может ли это быть запятой между select и distinct?
Ответы
Ответ 1
DISTINCT должен быть прямым после SELECT i.e.
SELECT DISTINCT(badges.id), "badges".* FROM "badges" INNER JOIN "userbadges" ON "badges".id = "userbadges".badges_id WHERE (("userbadges".user_id = 1))
Try:
@user.select("DISTINCT(badges.id), badges.*").badges.order("badges.created_at DESC")
PostgreSQL требует, чтобы у вас была инструкция заказа для отдельного поля:
@user.select("DISTINCT(badges.id), badges.*").badges.order("badges.id").order("badges.created_at DESC")
Ответ 2
Можно попробовать использовать группу
@user.badges.group(:id)
Ответ 3
Set
:uniq => true
в ассоциации. Или создайте отдельную ассоциацию только для уникальных значков пользователя.
http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_many
Что-то вроде
Class User < ActiveRecord::Base
has_many :user_badges
has_many :badges, :through => :user_badges
has_many :unique_badges, :through => :user_badges, :source => :badges, :uniq => true
#untested
end
Ответ 4
Попробуйте это
@user.badges.select("DISTINCT(badges.id)").order("badges.created_at DESC")
Ответ 5
У меня была аналогичная проблема с использованием PostgreSQL.
Мой код выглядел так:
User.find(2).devices.group('token')
Это вызвало ошибку:
Device Load (0.8ms) SELECT "devices".* FROM "devices" WHERE "devices"."user_id" = 2 GROUP BY token
ActiveRecord::StatementInvalid: PG::Error: ERROR: column "devices.id" must appear in the GROUP BY clause or be used in an aggregate function
Решение:
Изменение этой строки на:
User.find(2).devices.select('distinct token')
Отлично работает:
Device Load (1.3ms) SELECT distinct token FROM "devices" WHERE "devices"."user_id" = 2
=> [#<Device token: "example">, #<Device token: "example1">, #<Device token: "example2">, #<Device token: "example3">, #<Device token: "example4">, #<Device token: "example4">]
Update:
Извините, я не полностью изучил исходный вопрос и фактически ответил на другое сообщение в потоке, жалуясь на метод #group, не работающий с PostgreSQL. Это все же ценный ответ, поэтому я оставлю его.
Ответ 6
@user.badges.select("id").order("created_at DESC").uniq
Это работает для меня.
Ответ 7
Существует как минимум три способа получить уникальный список значков от пользователя:
-
@user.badges.group(:id)
-
@user.badges.select("DISTINCT badges.*")
- Или добавьте
:uniq => true
в строку has_many :badges, :through
Конечно, вы можете также связать ваш order("badges.created_at DESC")
с запросом.