Рельсы получают список записей с датой последней ассоциации - PullRequest
0 голосов
/ 01 мая 2020

У меня есть таблица users, таблица restaurants и таблица visits, которая объединяет оба. Я хочу вернуть список всех ресторанов вместе с последней датой посещения ресторана текущим пользователем.

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

Посещения:

Restaurant:      User:    Created at:
R1                 1          Mon
R1                 1          Tue
R1                 2          Tue
R2                 3          Thur
R4                 1          Wed
R4                 1          Fri

Предполагается текущий пользователь # 1, тогда я хочу вернуть что-то вроде:

Restaurant:      Last Visit At:
R1                 Tue
R2                 null
R3                 null
R4                 Fri

Пока что я попробовал:

def restaurants_with_last_visit(user)
  Restaurant.joins("LEFT JOIN visits ON visits.restaurant_id = restaurants.id AND visits.user_id = #{user.id}").select('restaurants.*, visits.created_at AS current_redeemed_at)
end

Но это не гарантирует, что я получу только каждый ресторан записывают один раз.

Я также пытался (основываясь на других ответах):

def restaurants_with_last_visit(user)
  Restaurant.joins('LEFT JOIN visits ON visits.restaurant_id = restaurants.id AND visits.user_id = #{user.id}).select("restaurants.*, max(visits.created_at) as current_reedemed_at").group('restaurants.id')
end

Но группа возвращает массив хешей вместо реальных записей.

Может кто-нибудь мне помочь? Это кажется таким простым, но таким трудным

1 Ответ

0 голосов
/ 01 мая 2020

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

Restaurant.select('restaurants.*, visits.created_at AS last_visited_at').joins('LEFT JOIN visits ON visits.restaurant_id = restaurants.id LEFT JOIN visits AS v ON  v.restaurant_id = visits.restaurant_id AND v.user_id = visits.user_id AND visits.created_at < v.created_at')
          .where('v.id IS NULL')
          .where('visits.user_id = ? OR visits.user_id IS NULL', 1)

Соедините таблицу visits с собой, и если нет записи с большим created_at, то есть последняя запись; также мы используем LEFT JOIN, и если v.id IS NULL для записи, это означает, что она не присоединилась.

Вы можете перебирать и получать доступ к значениям с помощью record['name'] и record['last_visited_at'].

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