Я уже знаю, как использовать Rails для создания подзапросов в условиях where
, например:
Order.where(item_id: Item.select(:id).where(user_id: 10))
Однако, как вы увидите, мой случай немного сложнее. Я пытаюсь преобразовать этот запрос:
Post.find_by_sql(
<<-SQL
SELECT posts.*
FROM posts
WHERE (
SELECT name
FROM moderation_events
WHERE moderable_id = posts.id
AND moderable_type = 'Post'
ORDER BY created_at DESC
LIMIT 1
) = 'reported'
SQL
)
в вызов типа ActiveRecord / Arel (i sh), но пока не смог найти способ, поэтому необработанный код SQL и использование find_by_sql
.
Мне интересно, сталкивался ли кто-нибудь уже с такой же проблемой и есть ли лучший способ написать этот запрос?
EDIT
Необработанный запрос выше работает и возвращает именно тот результат, который мне нужен. Я использую PostgreSQL.
Post model
class Post < ApplicationRecord
has_many :moderation_events, as: :moderable, dependent: :destroy, inverse_of: :moderable
end
ModerationEvent model
class ModerationEvent < ApplicationRecord
belongs_to :moderable, polymorphic: true
belongs_to :post, foreign_key: :moderable_id, inverse_of: :moderation_events
end
EDIT 2
Я пробовал использовать ассоциации Rails для запроса, используя includes
, joins
и т.п. Однако приведенный выше запрос очень конкретный c и хорошо работает с этой формой. Изменение его с помощью запроса JOIN
не возвращает ожидаемых результатов.
Операторы ORDER
и LIMIT
очень важны здесь и не могут быть перемещены за его пределы.
A post
может иметь несколько moderation_events
. Событие модерации может иметь несколько name
(он же тип): reported
, validated
, moved
и deleted
.
Вот что делает запрос:
Получение всех сообщений с последним событием модерации как «сообщенное» событие
Я не пытаюсь изменить приведенный выше запрос, потому что в нашем случае он работает хорошо и быстро. Я просто пытаюсь преобразовать его в более активный режим записи, не меняя, если возможно