ActiveRecord добавляет 'AND (1 = 0)' к концу запросов

Я играл в консоли rails, пытаясь заставить работать, и я постоянно замечаю, что один из моих запросов продолжает возвращать нуль, когда это не должно. Посмотрев на сгенерированный SQL-запрос, я заметил, что он каждый раз добавляет к нему AND (1=0). Это немного раздражает, и я не уверен, почему он это делает.

Примечание. Использование действующего драгоценного камня.

Шаги для воспроизведения:

(После подключения к столам в консоли rails)

2.1.2 :xxxx > @parent = Parent.take
Parent Load (38.1ms)  SELECT  `parents`.* FROM `parents`  LIMIT 1
 => #<Parent id: 37, ...>

2.1.2 :xxxx > @child = Child.where(id: @parent.actable_id)
SQL (0.7ms)  SELECT `childs`.`id` AS t0_r0, `childs`.`attribute` AS t0_r1, FROM `childs`
...
LEFT OUTER JOIN `parents` ON `parents`.`actable_id` = `childs`.`id` AND `parents`.`actable_type` = 'child type' WHERE `childs`.`id` = 20 AND (1=0)
 => #<ActiveRecord::Relation []>

Почему это происходит? Как заставить его остановиться?

Ответы

Ответ 1

Rails будет генерировать SQL как AND (1=0) при запросе для столбца, значение которого находится в пустом массиве:

Child.where(id: [])

Интуитивно, вы ожидаете, что генерировать SQL как SELECT * FROM children WHERE id IN (), но () на самом деле не является действительным SQL. Так как никакие строки не будут соответствовать этому запросу, Rails работает вокруг этого, создавая эквивалентный запрос, который также не возвращает никаких строк:

SELECT * FROM children WHERE 1=0;