Как использовать SQL с помощью Active Record - PullRequest
3 голосов
/ 30 мая 2019

Я пытаюсь оптимизировать производительность запроса в Active Record.Ранее я выполнял два SQL-запроса, и это должно быть возможно сделать одним.

Это таблицы, к которым я выполняю запросы:

# Table name: notifications
#
#  id         :integer          not null, primary key
#  content    :text(65535)
#  position   :integer

# Table name: dismissed_notifications
#
#  id              :integer          not null, primary key
#  notification_id :integer
#  user_id         :integer

Это существующий запрос:

where.not(id: user.dismissed_notifications.pluck(:id))

, который выдает:

SELECT `dismissed_notifications`.`id` FROM `dismissed_notifications` WHERE `dismissed_notifications`.`user_id` = 655

SELECT  `notifications`.* FROM `notifications` WHERE (`notifications`.`id` != 1)

Это SQL, который я хотел бы получить, который возвращает те же записи:

select *
from notifications n
where not exists(
    select 1
    from dismissed_notifications dn
    where dn.id = n.id
      and dn.user_id = 655)

1 Ответ

5 голосов
/ 31 мая 2019

Вы можете написать not exists Запрос, как показано ниже

where('NOT EXISTS (' + user.dismissed_notifications.where('dismissed_notifications.id = notifications.id').to_sql + ')')

OR

Существует также другой способ уменьшить количество запросов - использовать select вместо pluck, он будет создавать подзапрос вместо извлечения записей из базы данных. Rails-подзапросы ActiveRecord

where.not(id: user.dismissed_notifications.select(:id))

Который будет генерировать ниже SQL-запроса

SELECT  `notifications`.* 
  FROM `notifications` 
  WHERE (
    `notifications`.`id` NOT IN 
      (SELECT `dismissed_notifications`.`id` 
        FROM `dismissed_notifications` 
        WHERE `dismissed_notifications`.`user_id` = 655
      )
  )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...