Въз основа на факта, който сте открили, че [1..5]
не е правилният начин за определяне на диапазона... Открих защо [1..5]
се държи както го прави. За да стигна до там, първо открих, че празен масив в хеш условие произвежда 1=0
SQL условие:
User.where(id: []).to_sql
# => "SELECT \"users\".* FROM \"users\" WHERE 1=0"
И ако проверите ActiveRecord::PredicateBuilder::ArrayHandler код , ще видите, че стойностите на масива винаги са разделени на диапазони и други стойности.
ranges, values = values.partition { |v| v.is_a?(Range) }
Това обяснява защо не виждате 1=0
когато се използват стойности извън диапазона. Това е единственият начин да получите 1=0
от масив без включването на диапазон е да се предостави празен масив, който дава 1=0
състояние, както е показано по-горе. И когато целият масив има в него е диапазон, вие ще получите условията за диапазон (ranges
) и отделно условие за празен масив (values
) изпълнен. Предполагам, че няма основателна причина за това... просто е по-лесно да оставим това да бъде, отколкото да го избегнем (тъй като наборът от резултати е еквивалентен и в двата случая). Ако кодът на дяла беше малко по-интелигентен, тогава нямаше да се налага да използва допълнителните празни values
масив и може да пропусне 1=0
състояние.
Що се отнася до къде е 1=0
идва от на първо място... Мисля, че идва от адаптера на базата данни, но не можах да намеря точно къде. Въпреки това бих го нарекъл опит да не се намери запис. С други думи, WHERE 1=0
никога няма да върне потребители, което има смисъл спрямо алтернативен SQL като WHERE id=null
който ще намери всички потребители, чийто идентификатор е нулев (осъзнавайки, че това всъщност не е правилен SQL синтаксис). И това е, което бих очаквал, когато се опитвам да намеря всички потребители, чийто идентификатор е в празния набор (т.е. ние не искаме нулеви идентификатори или нулеви идентификатори или каквото и да било). Така че, според мен, оставям малкото за това къде точно 1=0
идва от като черна кутия е ОК. Сега поне можем да разсъждаваме защо диапазонът вътре в масива го кара да се показва!
АКТУАЛИЗИРАНЕ
Също така открих, че дори когато използвате ARel директно, все още можете да получите 1=0
:
User.arel_table[:id].in([]).to_sql
# => "1=0"