読者です 読者をやめる 読者になる 読者になる

【ActiveRecord】exists?の引数にwhereクエリの内容を書いてみたらうまくいかない。

Person.exists?(1) # => true
# SELECT  1 AS one FROM `job_offers`  WHERE `job_offers`.`id` = 1 LIMIT 1
Person.exists?('id = 1') #=> false
# SELECT  1 AS one FROM `job_offers`  WHERE `job_offers`.`id` = 0 LIMIT 1

なぜか?
exists?にArrayもしくはHashを引数で渡すと、where(condition).limit(1)とほぼ同じ挙動をする。
それ以外の引数を渡すと主キーでの検索を行おうとする。
ただし、findではなくPerson.where(id: 'id = 1')が呼ばれ、(この後はソースを読み切れていないが)エラーにならずWHERE job_offers.id = 0なんてクエリが発行されてしまうらしい。

解決策
whereと同じような挙動を期待する場合はArrayもしくはHashを与えれば良い。 したがって今回の場合であれば

Person.exists?(['id = 1']) #=> true
# SELECT  1 AS one FROM `job_offers`  WHERE (id = 1) LIMIT 1

となる。(カッコが付いてしまうのは仕方なさそう。) ActiveRecord:: FinderMethods#exists?