ActiveRecordのfindには"123ABC"という文字列を渡しても動く
結論
モデルのPrimary Keyが整数の場合、Person.find("123ABC")
という文字列を渡すとto_i
で数値に変換され、Person.find(123)
と評価される。
Person.find("123ABC")
↓
Person.find(123)
経緯
仮にPerson
というモデルがあり、Primary Keyが整数、/persons/:id
の形式で渡されるIDを使ってPerson.find(params[:id)
のようにクエリを投げている処理があるという前提。
アクセスログを眺めていたら/persons/123ABC
のように文字列を入れてアクセスしてきているケースがあった。
ActiveRecordのfind
では指定されたIDを持つレコードが見つからなければActiveRecord::RecordNotFound
がraiseされるはずが、普通にアクセスできてしまうことに気付く。(ID = 123
のレコードのデータが表示されている)
よくよくドキュメントを読んでみると以下の記載があった。
Person.find(1) # returns the object for ID = 1
Person.find("1") # returns the object for ID = 1
Person.find("31-sarah") # returns the object for ID = 31
If the primary key is an integer, find by id coerces its arguments by using to_i.
to_i
で数値に変換できる文字列ならいいので以下の形でも動く
Person.find(' 10')
Person.find('-10')
Person.find('+10')
Person.find('00010')
Person.find('+00010ABCDE')
↓ 全て以下と同じ結果になる
Person.find(10)
Person.find("1")
のように文字列で指定しても動くのは知ってたけど、Person.find("31-sarah")
のように数値以外の文字が含まれていても動くのは知らなかったので備忘録。
Author And Source
この問題について(ActiveRecordのfindには"123ABC"という文字列を渡しても動く), 我々は、より多くの情報をここで見つけました https://zenn.dev/nhsykym/articles/46c411c8c9a859著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Collection and Share based on the CC protocol