Подтвердить что ты не робот

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?

4b9b3361

Ответ 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") с запросом.