Basandosi sul fatto, che hai scoperto, che [1..5]
non è il modo corretto per specificare l'intervallo... ho scoperto perché [1..5]
si comporta come fa. Per arrivarci, per prima cosa ho scoperto che un array vuoto in una condizione hash produce il 1=0
Condizione SQL:
User.where(id: []).to_sql
# => "SELECT \"users\".* FROM \"users\" WHERE 1=0"
E, se controlli ActiveRecord::PredicateBuilder::Codice ArrayHandler , vedrai che i valori dell'array sono sempre partizionati in intervalli e altri valori.
ranges, values = values.partition { |v| v.is_a?(Range) }
Questo spiega perché non vedi 1=0
quando si utilizzano valori non compresi nell'intervallo. Cioè, l'unico modo per ottenere 1=0
da un array senza includere un intervallo è fornire un array vuoto, che restituisce il 1=0
condizione, come mostrato sopra. E quando tutto ciò che l'array contiene è un intervallo, otterrai le condizioni dell'intervallo (ranges
) e, separatamente, una condizione di matrice vuota (values
) eseguito. La mia ipotesi è che non ci sia una buona ragione per questo ... semplicemente è più facile lasciare che sia così che evitarlo (poiché il set di risultati è equivalente in entrambi i casi). Se il codice della partizione fosse un po' più intelligente, non dovrebbe aggiungere i values
vuoti aggiuntivi array e potrebbe saltare il 1=0
condizione.
Per quanto riguarda dove il 1=0
viene da in primo luogo ... Penso che provenga dall'adattatore del database, ma non sono riuscito a trovare esattamente dove. Tuttavia, lo definirei un tentativo di non riuscire a trovare un record. In altre parole, WHERE 1=0
non restituirà mai alcun utente, il che ha senso su SQL alternativo come WHERE id=null
che troverà tutti gli utenti il cui ID è nullo (rendendosi conto che questa non è la sintassi SQL realmente corretta). E questo è quello che mi aspetterei quando tento di trovare tutti gli utenti il cui ID è nel set vuoto (cioè non stiamo chiedendo ID nulli o ID nulli o altro). Quindi, nella mia mente, lasciando il bit su dove esattamente 1=0
viene da come una scatola nera è OK. Almeno ora possiamo ragionare sul motivo per cui l'intervallo all'interno dell'array lo sta causando!
AGGIORNAMENTO
Ho anche scoperto che, anche utilizzando ARel direttamente, puoi comunque ottenere 1=0
:
User.arel_table[:id].in([]).to_sql
# => "1=0"