Berdasarkan fakta yang Anda temukan, bahwa [1..5]
bukan cara yang benar untuk menentukan rentang... Saya telah menemukan mengapa [1..5]
berperilaku seperti itu. Untuk sampai ke sana, saya pertama kali menemukan bahwa array kosong dalam kondisi hash menghasilkan 1=0
Kondisi SQL:
User.where(id: []).to_sql
# => "SELECT \"users\".* FROM \"users\" WHERE 1=0"
Dan, jika Anda memeriksa ActiveRecord::PredicateBuilder::ArrayHandler code , Anda akan melihat bahwa nilai larik selalu dipartisi ke dalam rentang dan nilai lainnya.
ranges, values = values.partition { |v| v.is_a?(Range) }
Ini menjelaskan mengapa Anda tidak melihat 1=0
saat menggunakan nilai non-rentang. Artinya, satu-satunya cara untuk mendapatkan 1=0
dari larik tanpa menyertakan rentang adalah menyediakan larik kosong, yang menghasilkan 1=0
kondisi, seperti gambar di atas. Dan ketika semua array memiliki rentang, Anda akan mendapatkan kondisi rentang (ranges
) dan, secara terpisah, kondisi larik kosong (values
) dieksekusi. Dugaan saya adalah bahwa tidak ada alasan yang baik untuk ini ... hanya saja lebih mudah untuk membiarkan ini terjadi daripada menghindarinya (karena set hasil sama saja). Jika kode partisi sedikit lebih pintar maka tidak perlu menambahkan values
tambahan yang kosong array dan dapat melewati 1=0
kondisi.
Adapun di mana 1=0
berasal dari tempat pertama... Saya pikir itu berasal dari adaptor database, tetapi saya tidak dapat menemukan dengan tepat di mana. Namun, saya akan menyebutnya sebagai upaya untuk gagal menemukan catatan. Dengan kata lain, WHERE 1=0
tidak akan pernah mengembalikan pengguna mana pun, yang masuk akal dibandingkan SQL alternatif seperti WHERE id=null
yang akan menemukan pengguna yang idnya nol (menyadari bahwa ini bukan sintaks SQL yang benar). Dan inilah yang saya harapkan ketika mencoba menemukan semua Pengguna yang id-nya ada di set kosong (yaitu kami tidak meminta nil id atau null id atau apa pun). Jadi, dalam pikiran saya, meninggalkan sedikit tentang di mana tepatnya 1=0
berasal dari sebagai kotak hitam OK. Setidaknya kita sekarang dapat menjelaskan mengapa rentang di dalam array menyebabkannya muncul!
PERBARUI
Saya juga menemukan bahwa, bahkan saat menggunakan ARel secara langsung, Anda masih bisa mendapatkan 1=0
:
User.arel_table[:id].in([]).to_sql
# => "1=0"