PIYO - Tech & Life -

Railsのredirect_toでちょっとだけはまる

普通にRails書いていてどうもうまくいかないところがあってはまったのでメモしておく。

フォーム埋めてcreateアクションにPOSTしたあと、モデルのsaveが成功したらindexアクションへリダイレクト、失敗したらもう1回newをレンダリングというよくあるケース。これで保存に成功してindexにリダイレクトしたとき、なぜかURLに?notice=successがくっついてしまうということがあった。

実際に書いたコード(とほぼ同じもの)はこちら。

def create
  @entry = Entry.new(permitted_params)
  if @entry.save
    redirect_to action: :index, notice:"success"
  else
    render :new
  end
end

実は上のコードだと問題があるが、気を抜いていたので見落としてしまった。

redirect_toはこのようにハッシュの引数を2つ受け取る。

redirect_to(options = {}, response_status = {})

さきほどのケースでは暗黙のうちにactionnoticeも1つ目のハッシュであると解釈されてしまった。

redirect_to({action: :index, notice:"success"})

Rubyではメソッドの引数になるハッシュの波カッコは省略できるし、メソッドの引数も省略できることもあるのでどちらが優先されるのかが一見するとわかりにくい。

正しく動かすには以下のようにする必要がある。

def create
  @entry = Entry.new(permitted_params)
  if @entry.save
    redirect_to({action: :index}, notice:"success")
  else
    render :new
  end
end

一応これでうまくいった。