Edited at

Railsのform_forをview以外で使ってハマった。

More than 5 years have passed since last update.

Railsでform_forを使ってhelperを作っていたところ、ハマったのでメモ。

「クリックするとUserのlikedがインクリメントされるボタン」を出力するhelperを作るとします。初めに書いたのが、下のようなコード。

module UsersHelper

def like_button(user)
form_for(user) do |f|
f.hidden_field :liked, value: user.liked + 1
f.submit
end
end
end

likedの値をひとつ増やした隠しフィールドを含んだformをsubmitするというシンプルなもの。

しかし、submitボタンをクリックしても値が更新されない。

HTMLを見ても、隠しフィールドは出力されていませんでした。

そこで、小一時間悩んで出た答えが次のコード。

module UsersHelper

def like_button(user)
form_for(user) do |f|
str = ""
str << f.hidden_field(:liked, value: user.liked + 1).to_s
str << f.submit.to_s
str.html_safe
end
end
end

試行錯誤した結果、form_forブロックはブロックの返り値を返すみたいです。

普段は途中の文字列も<%= %>でerbに書き出しているため、意識してませんでした。

気付いてみれば大したことない感じですが、気づくまでに時間がかかったのでメモ。

そもそも、あまりキレイじゃないし、こういう処理はコントローラに書いたほうが良いのだろうか?