Код, который вы опубликовали, не только труден для отслеживания, но я помню, что у нас была большая утечка памяти, связанная с кэшированием ActiveReocrd при использовании предварительно вычисленных идентификаторов в запросе.
При этом я бы попытался использоватьвыше в одном запросе sql:
def call
id_select = InquiryProcess
.joins(inquiry_field_responses: :inquiry_field)
.where(inquire_fields: { name: 'company_name' })
.where(InquiryField.arel_table[:value].matches("#{company_filter}%"))
.select(:id)
InquiryProcess.where(id: id_select)
end
Обратите внимание, что id_select
это не массив идентификаторов, а область ActiveRecord, приведенное выше будет переводиться в следующий SQL:
SELECT "inquiry_processes".*
FROM "inquiry_processes"
WHERE "inquiry_processes"."id" IN (
SELECT "inquiry_processes"."id"
FROM "inquiry_processes"
INNER JOIN ...
WHERE ...
)
Ичтобы ответить на другой вопрос - почему мы запрашиваем таблицу, сопоставляя id с результатом другого подзапроса в той же таблице? Это позволяет избежать всевозможных болезненных проблем, когда вы имеете дело с активным отношением записи, в котором есть соединение - например, это повлияет на все дальнейшие операторы includes
, так как предварительно загруженная ассоциация будет включать только записи, соответствующие условиям соединения отношения.
Я очень надеюсь, что этот бит достаточно хорошо протестирован, или у вас есть кто-то, кто может проверить правильность поведения.