Na základě skutečnosti, kterou jste objevili, že [1..5]
není správný způsob, jak specifikovat rozsah... Zjistil jsem proč [1..5]
chová se tak, jak se chová. Abych se tam dostal, nejprve jsem zjistil, že prázdné pole v hašovací podmínce vytváří 1=0
SQL podmínka:
User.where(id: []).to_sql
# => "SELECT \"users\".* FROM \"users\" WHERE 1=0"
A pokud zkontrolujete Kód ActiveRecord::PredicateBuilder::ArrayHandler , uvidíte, že hodnoty pole jsou vždy rozděleny do rozsahů a dalších hodnot.
ranges, values = values.partition { |v| v.is_a?(Range) }
To vysvětluje, proč nevidíte 1=0
při použití hodnot mimo rozsah. To je jediný způsob, jak získat 1=0
z pole bez zahrnutí rozsahu je poskytnout prázdné pole, které dává 1=0
stavu, jak je uvedeno výše. A když všechno pole má rozsah, dostanete podmínky rozsahu (ranges
) a samostatně podmínku prázdného pole (values
) popraven. Hádám, že pro to není dobrý důvod... prostě je jednodušší to nechat být, než se tomu vyhnout (protože výsledná sada je v obou případech ekvivalentní). Pokud by byl kód oddílu o něco chytřejší, nemusel by se zaměřovat na další prázdné values
pole a mohl by přeskočit 1=0
podmínka.
Pokud jde o to, kde 1=0
pochází z prvního místa... Myslím, že pochází z databázového adaptéru, ale nemohl jsem najít přesně kde. Nazval bych to však snahou o neúspěšné nalezení záznamu. Jinými slovy WHERE 1=0
nikdy nevrátí žádné uživatele, což dává smysl oproti alternativním SQL, jako je WHERE id=null
který najde všechny uživatele, jejichž id je null (s vědomím, že to není ve skutečnosti správná syntaxe SQL). A to bych očekával při pokusu o nalezení všech uživatelů, jejichž ID je v prázdné sadě (tj. nepožadujeme nulová id nebo nulová id nebo cokoli jiného). Takže, v mé mysli, ponechám bit o tom, kde přesně 1=0
pochází z jako černá skříňka je v pořádku. Přinejmenším nyní můžeme uvažovat o tom, proč rozsah uvnitř pole způsobuje jeho zobrazení!
AKTUALIZACE
Také jsem zjistil, že i když používáte přímo ARel, stále můžete získat 1=0
:
User.arel_table[:id].in([]).to_sql
# => "1=0"