Rails Database Query .order GREATEST игнорировать, если NULL или пусто - PullRequest
0 голосов
/ 16 февраля 2020

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

Отношения :

  • a Обсуждение has_many сообщений.
  • a Пост has_many комментариев.
  • a Пользователь has_many сообщений.
  • a Пользователь has_many комментариев.
  • обсуждение has_many комментариев через сообщения.

Мой запрос в значительной степени работает, но только когда в обсуждении существуют и сообщение, и комментарий пользователя.

Как я мог отрегулируйте мой запрос, чтобы найти либо сообщение last_created post, либо last_created, то есть в моем .order как я могу игнорировать MAX(comments.created_at), если он пуст, и просто использовать MAX(posts.created_at)

@discussions = Discussion.
  joins(:posts,:comments).
  where(posts: {user: current_user}).
  where(comments: {user: current_user}).
  group('discussions.id').
  order('GREATEST(MAX(posts.created_at), MAX(comments.created_at)) DESC')

Ответы [ 2 ]

1 голос
/ 16 февраля 2020

Я бы начал с чего-то вроде этого:

@discussions = Discussion
  .left_outer_joins(:posts)
  .left_outer_joins(:comments)
  .where("posts.user_id = :id OR comments.user_id = :id", id: current_user.id)
  .group('discussions.id')
  .order('GREATEST(MAX(posts.created_at), MAX(comments.created_at)) DESC')

Вам нужно будет использовать

  • left_outer_joins, иначе при объединении будет найдено Обсуждение только с соответствующим постом и соответствующий комментарий
  • a where условие с OR, потому что может быть только запись или комментарий от текущего пользователя в строке после присоединения
0 голосов
/ 16 февраля 2020

Я думаю, что две вещи проблематичны c в вашем запросе:

  • оператор joins
  • операторы where, которые используют ссылку на таблицу ( пользователи), которые не были присоединены

Попробуйте изменить joins на left_joins, например, и обновите условие where, чтобы оно не зависело от присоединения пользователей. стол - который может вызвать другие проблемы.

@discussions = Discussion.
  left_joins(:posts,:comments).
  where('? IN (posts.user_id, comments.user_id)', current_user.id)
  group('discussions.id').
  order('GREATEST(MAX(posts.created_at), MAX(comments.created_at)) DESC')

Действительно, с помощью обычного INNER JOIN (что и делает метод joins под капотом), вы будете получать только те обсуждения, для которых есть и комментарий, и публикация вашего пользователя, которая это не то, что вы хотите сделать.

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