2019年10月17日 追記
Rails6
以降には form_for
, form_tag
を廃止にする宣言があるみたいです
Note: For 5.x, form_for and form_tag should just be soft deprecations, no warnings. Then we can deprecate with a warning, perhaps, in Rails 6.x.
環境
OS X 10.11.4
ruby -v 2.3.0
rails -v 4.2.5
#ハマったこと
<%= form_for @hoge do |f| %>
# 省略
<% end %>
上のようにform_forメソッドを利用しようとしたとき、オブジェクトを渡せばパスを指定してなくてもRailsが上手に繋げてくれるはずと思っていたのですが、
NoMethodError undefined method `hoges_path'
エラーになってしまう。
解決策を書いてくれている記事は結構あって感謝でしたが、原因がわからないと気持ち悪いなーと思ったので調べてみました。
#原因
form_forが自動的に生成してくれるパスが複数形のみだった。
$ rake routes
# 本来のroutes
hoge_index POST /hoge(.:format) hoge#create
# form_forが欲しかったroutes
hoges_index POST /hoge(.:format) hoge#create
# ↑複数形
RubyonRailsガイドにも載ってました。
ある長年の未解決バグ が原因で、form_forでは単数形リソースを自動的に扱えません。これを解決するには、以下のようにフォームのurlを直接指定します。
Rails のルーティング
解決策
以下のようにurl:を指定してあげるだけ、
<%= form_for @hoge, url: hoge_index_path do |f| %>
# 省略
<% end %>
好みだと思いますが、これでも動きます。
<%= form_for @hoge, :url => { :controller => :hoge, :action => :create } %>
# 省略
<% end %>