Rails: упорядочить результаты, возвращенные из DISTINCT ON * ORDER - PullRequest
0 голосов
/ 17 февраля 2020

У меня есть следующие модели Rails: Chat и Messages, где в чате может быть много сообщений. У меня есть следующий запрос Rails, чтобы получить последнее сообщение от пользователя для каждого чата, где он является получателем:

def index
  messages = Message.where(recipient_id: id)
                    .select('DISTINCT ON ("chat_id") *')
                    .order(:chat_id, created_at)
end

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

sorted = messages.order(created_at: :desc)

Он не сортирует результаты первого запроса, он просто добавляет порядок к первому запросу (что, как я знаю, является ожидаемым поведением). ) поэтому я не получаю отсортированный список по дате создания. Как я могу сделать заказ по результату первого запроса? По сути то, что имитирует c следующее с синтаксисом Rails:

SELECT *
FROM (SELECT DISTINCT ON (chat_id) *
      FROM messages
      ORDER BY chat_id, created_at DESC) last_messages
ORDER BY created_at DESC

Ответы [ 3 ]

4 голосов
/ 17 февраля 2020

попробуйте

Message.from(
  Message.where(recipient_id: id)
    .select('DISTINCT ON ("chat_id") *')
    .order("chat_id, created_at DESC"), 
    :messages
).order(created_at: :desc)
2 голосов
/ 17 февраля 2020

Вы могли бы сделать что-то вроде этого -

def index
  messages = Message.where(recipient_id: id)
                .select('DISTINCT ON ("chat_id") *, created_at')
                .order(:chat_id, created_at)
                .sort_by(&:created_at).reverse
end
1 голос
/ 17 февраля 2020

Первый вариант - unscope :order из messages, затем закажите его снова с нужным столбцом.

sorted = messages.unscope(:order).order(created_at: :desc)

В случае, если вы не можете отсканировать messages, другой вариант превращает messages в подзапрос.

sorted = Message.where(id: messages).order(created_at: :desc)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...