Учитывая следующее:
has_many
коллекционерыhas_one
gs_collectorhas_one
модельtitle
.Как мне в одном запросе получить все названия моделей внутри любого проекта без использования map
или чего-то подобного И без возникновения проблемы N + 1?
Используя map
, у меня есть различные работающие решения, но все они запрашивают базу данных более одного раза:
Project.joins(collectors: { gs_collector: :model }).find(92666).collectors.map{ |coll| coll.gs_collector.model.title }
Вы можете сделать что-то вроде этого
Model.joins(gs_collector: :collector).where(collectors: { project_id: 92666 }).pluck(:title)
Не знаю, почему за это проголосовали, это правильный способ сделать это. Также можно упростить, добавив немного has_one :through
к промежуточным звеньям, и AR выполнит соединения неявно.
Вы неправильно поняли, для чего используется
joins
.joins
на самом деле не используется для быстрой загрузки записей и решения распространенной проблемы n+1. Он используется для добавления предложения INNER JOIN, которое можно использовать для фильтрации строк, не имеющих совпадений в таблице соединения, или для добавления условий на основе таблицы соединения. Ни один столбец в объединенной таблице не будет выбран. Для нетерпеливой загрузки вы используете нетерпеливую загрузку, предварительную загрузку или включение. bigbinary.com/blog/preload-vs-eager-load-vs-joins-vs-includes