普通に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 = {})
さきほどのケースでは暗黙のうちにactionもnoticeも一つ目のハッシュであると解釈されてしまった。
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
一応これでうまくいった。