Почему функции базы данных ломают план запроса рельсов на включениях? - PullRequest
0 голосов
/ 04 мая 2019

Простой вызов работает как задумано. Результирующий SQL использует LEFT OUTER JOIN s для связывания таблиц по желанию.

> Subscription.includes(plan: { student: :person }).order('persons.name')
=> #<ActiveRecord::Relation ... >

Если функция вставляется в предложении order , кажется, что rails выходит из-под контроля в своем плане запросов, поскольку результирующий SQL не выполняет связывание таблиц и, следовательно, выдает ошибку:

> Subscription.includes(plan: { student: :person }).order('unaccent(persons.name)')
=> ActiveRecord::StatementInvalid (PG::UndefinedTable: ERROR:  missing FROM-clause entry for table "persons")
LINE 1: ...subscriptions".* FROM "subscriptions" ORDER BY unaccent(persons.na...
                                                             ^
: SELECT  "subscriptions".* FROM "subscriptions" ORDER BY unaccent(persons.name) LIMIT $1

То же самое не относится к объединениям , которые выполняют команду НО, используя INNER JOIN s в качестве связи таблицы (не совсем предполагаемое отношение)

> Subscription.joins(plan: { student: :person }).order('unaccent(persons.name)')
=> #<ActiveRecord::Relation ... > # GOOD

Как новичок здесь, что мне не хватает?

1 Ответ

0 голосов
/ 05 мая 2019

(переписано из моего комментария выше)

Вам необходимо добавить .references(:persons) к запросу.

Rails пытается быть "ленивым" и избегать ненужных JOIN с при использовании includes. Использование этой unaccent функции SQL отбрасывает планировщик запросов ActiveRecord, поэтому вам нужно быть более явным, что заставляет рельсы выполнять JOIN.

См. документацию по "условиям" :

Если вы хотите добавить условия к включенным моделям, вам придется явно ссылаться на них. Например:

User.includes(:posts).where('posts.name = ?', 'example')

выдаст ошибку, но это будет работать:

User.includes(:posts).where('posts.name = ?', 'example').references(:posts)

Обратите внимание, что включает в себя работы с имена связей, в то время как для ссылок требуется фактическое имя таблицы

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...