普通に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も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
一応これでうまくいった。