SQL の NULL に問題があります。where真ん中のもの:
where('id not in (?)', nil)
次の SQL になります。
id not in (null)
そしてそれはこれと同等です:
id != null
しかし、 の結果id != nullは真でも偽でもありません。結果は NULL で、ブール値コンテキストの NULL は偽です。実際、x = null結果x != nullはすべて NULL になりますx(xそれ自体が NULL であっても)。たとえば、PostgreSQL では次のようになります。
=> select coalesce((11 = null)::text, '-NULL-');
coalesce
----------
-NULL-
(1 row)
=> select coalesce((11 != null)::text, '-NULL-');
coalesce
----------
-NULL-
(1 row)
=> select coalesce((null = null)::text, '-NULL-');
coalesce
----------
-NULL-
(1 row)
=> select coalesce((null != null)::text, '-NULL-');
coalesce
----------
-NULL-
(1 row)
MySQL およびその他の適切に準拠したデータベースはすべて同じことを行います (NULL を明確にするためのキャスト要件が異なる可能性があります)。
その結果、where(id not in (?)', nil)常に空のセットが生成され、空のセットでは存在チェックが常に失敗します。
id「 NULL でないすべての行」と言いたい場合は、次のように言います。
where('id is not null')
あなたidが主キーである場合(ほぼ確実にそうです)、idNULLになることはなく、where完全に省略できます。
whereだけを渡す場合nil:
where(nil)
wherenilの引数解析ロジックは を完全に無視し、where(nil)と同じになり、クエリに対して何もしませんwhere()。where()その結果、データベースに関する限り、1 番目と 3 番目のクエリは同じになります。