未分類 | 5月 20th, 2009
RailsのActiveRecordで、save! とかすると保存に失敗したとき例外を投げてくれる。例えば、User.create!(params[:user]) とかして、失敗すると、ActiveRecord::RecordInvalid を投げてくれるのだけど、エラーをどうやって取るのか調べたのでメモ。
よくある例で、ユーザが作れたら index へ遷移して、作れなかったら new で再入力させるという場合。
createを使う場合
def create if @user = User.create(params[:user]) flash[:notice] = 'ユーザ作成しました' redirect_to :action => 'index' else # ここでは、@user.errors でエラーが取れる render :action => 'new' end end
create!を使う場合
def create @user = User.create!(params[:user]) flash[:notice] = 'ユーザ作成しました' redirect_to :action => 'index' rescue ActiveRecord::RecordInvalid => e # @user は nil になっているので、 @user.errors でエラーが取れない。 render :action => 'new' end
としたとき、create! で例外が飛んでいるので、当然 @user は nil となってます。なので、rescue 句の中で @user.errors ではエラーが取れません。
調べたところ、e.record で、ActiveRecord の例外を発生させたインスタンスが取れるようです。
def create @user = User.create!(params[:user]) flash[:notice] = 'ユーザ作成しました' redirect_to :action => 'index' rescue ActiveRecord::RecordInvalid => e # e.record に Userクラスのインスタンスが入ってる。 @user = e.record render :action => 'new' end
たとえば、View内で
< %= error_messages_for :user %>
とかしたい場合は、@user = e.record として置けばエラーが楽に表示出来て良い。




