Я использую Rails 4.2.0 с ActiveRecord. У меня есть Case
модель, которая has_many :notes
.Подзапрос для левого соединения в области объединения в рельсах
Моя основная цель - получить последнее примечание для каждого случая в одном запросе. Примечание поле должно быть сортировкой (ORDER BY notes.created_at
, к примеру) я мог бы добиться этого с помощью такой SQL запроса:
SELECT cases.*, notes.* FROM cases
LEFT OUTER JOIN notes ON cases.id = notes.case_id AND notes.id = (
SELECT id FROM notes
WHERE notes.case_id = cases.id
ORDER BY notes.created_at DESC
LIMIT 1
)
ORDER BY notes.created_at DESC
Моего текущего case.rb
кода следующий:
has_one :latest_note, -> do
where('id' => Note.where('"case_id" = "cases"."id"').order(created_at: :desc).limit(1))
end, inverse_of: :case, class_name: 'Note'
Он отлично работает, когда eager_load
используется: Case.eager_load(:latest_note).order('notes.created_at DESC')
SELECT "cases"."id" AS t0_r0, "cases"."created_at" AS t0_r1, "cases"."updated_at" AS t0_r2, "notes"."id" AS t1_r0, "notes"."case_id" AS t1_r1, "notes"."created_at" AS t1_r2, "notes"."updated_at" AS t1_r3
FROM "cases" LEFT OUTER JOIN "notes"
ON "notes"."case_id" = "cases"."id"
AND "notes"."id" IN (
SELECT "notes"."id" FROM "notes"
WHERE ("case_id" = "cases"."id")
ORDER BY "notes"."created_at" DESC
LIMIT 1
) ORDER BY notes.created_at DESC
Но возникает ошибка SQLite3::SQLException: no such column: cases.id
без eager_load
: Case.first.latest_note
SELECT "notes".* FROM "notes"
WHERE "notes"."case_id" = ? AND "notes"."id" IN (
SELECT "notes"."id" FROM "notes"
WHERE ("case_id" = "cases"."id")
ORDER BY "notes"."created_at" DESC
LIMIT 1
) LIMIT 1
P.S. Есть ли решение без связей? Сырые левые соединения через joins
не работают с eager_load
. Без eager_load
он не отображает значения из базы данных в объекты - даты остаются как строки, а не DateTime
объектов.
избежать предупреждений с помощью объединения вместо экземпляра-зависимый, где положение: 'has_many: birthday_events, -> {присоединяется («JOIN events on events.starts_on = users.birthday»}, class_name: «Событие» – s2t2