Я думаю, что основная проблема с вашим исходным AR-запросом заключается в том, что он вообще не выполняет никаких соединений; вы вытаскиваете кучу объектов из базы данных через @list.contacts
, а затем отбрасываете большую часть этой работы, чтобы получить только идентификаторы.
Первым шагом будет замена "contacts_lists.contact_id" => @list.contacts.map(&:id)
на :joins => 'contact_lists'
, но вы все равно будете вытаскивать кучу вещей из базы данных, создавать экземпляры группы объектов, а затем выбрасывать все это с помощью .map(&:id)
, чтобы получить только идентификационные номера.
Вы уже знаете SQL, поэтому я, вероятно, сразу перейду к SQL с помощью удобного метода в вашей модели List (или каков @list
), что-то вроде этого:
def checked_contact_ids
connection.execute(%Q{
SELECT contacts.id
FROM contacts
INNER JOIN contacts_lists ON contacts.id = contacts_lists.contact_id
WHERE contacts_lists.list_id = #{self.id}
AND contacts_lists.is_checked = 't'
}).map { |r| r['id'] }
end
А потом, в вашем контроллере:
@checked_contact_ids = @list.checked_contact_ids
Если этого недостаточно, проверьте ваши индексы в таблице contacts_lists
.
Нет веской причины не переходить прямо к SQL, когда вы точно знаете, какие данные вам нужны, и вам это нужно быстро; просто держите SQL изолированным внутри ваших моделей, и у вас не должно возникнуть никаких проблем.