はっまった ^^); ・・・ ActiveRecod.find(id) の id は文字列でも良いが、全てのAPIがそうなわけではない!

午前中Railsを使った仕事で1時間近くハマッてしまいました・・・・なかなか原因がわからず、Railsのソースを読み Rails自体のライブラリーに適当なdebugログを入れてやっと気がつきました!

RubyPerlPHP と違い型の自動変換が起こることはありません。したがって整数を期待しているメソッドに "123" のような数字だけだけの文字列を渡してもエラーに成ることが多いです。


RailsActiveRecordRDBのレコードを一意に識別するためのidを持っています。そして、id は整数です。
したっがて、レコードを取得する find()メソッドには通常、整数の id 値を渡します。

% script/console 
>> Todo.find(1)
=> #<Todo id: 1, due: "2008-08-26", task: "Ruby on Railsの勉強", 
     created_at: "2008-08-16 12:35:02", updated_at: "2008-08-18 07:58:17">

しかし、"1"のような文字列をid値としてもレコードが取得できます。

% script/console 
>> Todo.find("1")
=> #<Todo id: 1, due: "2008-08-26", task: "Ruby on Railsの勉強", 
     created_at: "2008-08-16 12:35:02", updated_at: "2008-08-18 07:58:17">

これは、Scaffoldが作る以下のようなコードでも 文字列から整数への変換メソッドをいちいち書かなくて良いとの親切心だと思います ^^)

    @todo = Todo.find(params[:id])

本来なら以下のように書くべきですが・・・

    @todo = Todo.find(params[:id].to_i)


しかし、全ての ActiveRecordAPI でこの考えが適応されているわけではありません


今回のハッマッた問題は、 配列等の値からoptionタグを作成してくれる、ActionView::Helpers::FormOptionsHelper.options_for_select(container, selected) で正しく selected値を渡しているつもりなのに、select boxに上手く表示されない現象でした。


原因は、私の勘違いで、 selected に渡る値が文字列だったのです。
debugログ等では 1 と "1" の区別が難しく、 find()で選択できる id 値を使っているので id は数値と思いこんでいた事が発見を遅らせていました (-。-;)