Неправильное поведение запроса ActiveRecord для внешних соединений?

#sql #ruby-on-rails #ruby #activerecord

#sql #ruby-on-rails #ruby #activerecord

Вопрос:

Давайте рассмотрим две модели ActiveRecord Product и Promotion

Построение запроса с использованием внешнего соединения и псевдонима для столбца объединенной таблицы приводит к следующему недопустимому SQL:

 Product.distinct.includes(:promotion).select('promotions.advertised as featured').
references(:promotion).order('featured').limit(10).to_sql

SELECT  DISTINCT "products"."id", featured AS alias_0 FROM "products"
                                  ^^^^^^^^^^^^^^^^^^^
 LEFT OUTER JOIN "promotions" ON "promotions"."product_id" = "products"."id"  ORDER BY featured LIMIT 10
  

Результатом выполнения является ошибка базы данных: ActiveRecord::StatementInvalid: PG::UndefinedColumn: ERROR: column "featured" does not exist . Как и ожидалось, потому что featured является псевдонимом для столбца promotions.advertised, не определенного в таблице products.

Как вы можете видеть, ActiveRecord вводит недопустимое "featured AS alias_0" выражение в select. Кроме того, все столбцы products таблицы, за исключением id , опущены.

Вышеуказанное неправильное поведение связано с одновременным использованием методов order И limit . Когда какой-либо из них опущен, созданный SQL становится правильным. Например, простое удаление limit приводит к правильному запросу:

 Product.distinct.includes(:promotion).select('promotions.advertised as featured').
references(:promotion).order('featured').to_sql

SELECT  DISTINCT promotions.advertised as featured, "products"."id" AS t0_r0, "products"."name" AS t0_r1, … FROM "products"
LEFT OUTER JOIN "promotions" ON "promotions"."product_id" = "products"."id"  ORDER BY featured
  

Кто-нибудь может объяснить это поведение?

Кандидат на сообщение об ошибке или я что-то упускаю?

протестировано с ActiveRecord версии 4.2.7.1

Комментарии:

1. distinct это не проблема. Не влияет на исправление неверного запроса, если он пропущен. Я пытался упростить гораздо более сложную проблему, но основная идея сохранена. Я не совсем понимаю, что вы подразумеваете под «борьбой» с вышеуказанными методами, почему их не следует использовать вместе.

2. Под «борьбой» я подразумеваю, что distinct , includes и select все пытаются что-то сделать с предложением SELECT, и, похоже, в конечном итоге они все портят.

3. Я все еще не вижу никакой двусмысленности или неправильного использования этих методов. Что меня беспокоит, и, вероятно, должно беспокоить других, он молча возвращает явно неправильный результат, просто добавляя совершенно несвязанный limit метод.