ActiveRecord::Base#findの例外

ActiveRecord::Baseを継承したクラスでIDからレコードを引っ張り出したいという場合はよくある話。僕はよく有効なIDであるかどうかをfindの帰り値がnilかどうかで調べるんですが、ActiveRecord::Base#find(id)を使うと存在しないレコードのIDの場合例外が発生することがわかりました。↓のようなコードですね。


if !User.find(params[:id]) then
logger.debug "user does not exist"
end

例外が投げられることによって(僕が)期待したように動作しませんでした。(僕が)期待するように動かすには以下の3つのアプローチがあるようです。

  • 1. begin〜rescue〜endを使って例外をトラップする
  • 2. ActiveRecord::Base#find(:first, :conditions => {:id => id})を使う
  • 3. find_by_id(id)を使う

コードで書くと以下のよう。


# 1.
begin
u = User.find(params[:id])
rescue
logger.debug "user does not exist"
end


# 2.
if !User.find(:first, :conditions => {:id => params[:id]}) then
logger.debug "user does not exist"
end

# 3.
if !User.find_by_id(params[:id]) then
logger.debug "user does not exist"
end

3番のfind_by_idは動的にメソッド名を決定する仕組みを使っている気がするのでボトルネックになるような処理では他の方法の方がいいかもしれませんね。(そもそもそんなに処理速度が重要ならAR使わないって?ごもっとも...)