はじめに...
Railsでよく利用するlink_to ですが、豊富なオプションのおかげでついつい、こんなコードを書いていました。
link_to "create", xxx_xxxx_path(xxx_id: xxx, xxx_id: xxx), method: :post, remote: true ...
今回は、このコードに感じる違和感の話です。
どこが気持ち悪いのか...
ズバリ method: :post です。
この指定をしたとき、出力されるhtmlはこうなります。
<a href="xxx/xxxx" data-method="post" ...">create</a>
.... anchorタグにpostがついていますね。
「a タグに"post"」 ってどういうことでしょう?
うーん、ぱっと理解できません。
なぜ気持ち悪いのか....
先ほどのコードの気持ち悪さは、aタグの基本的な使い方からずれてるところからきています。
The <a> tag defines a hyperlink, which is used to link from one page to another.
となっています。
この定義に従うのなら、httpメソッドとしては、(必然的に)getです。
....htmlでは、aタグの定義にhttpメソッドはそもそも指定できませんしね。
これが、違和感の正体です。
より自然に読めるコードにするには、
これらの違和感を解消するためのコードとしては、
link_to では、get しか使わない。
という制約を課すことだと思います。
postメソッドはform_forしか指定しない。
言い換えると、
UrlHelperで使われる デフォルトのhttpメソッドは変えない。
ということだと思います。
制約を課したときの例
これまで説明した制約の元で、link_toのほとんどは
以下のようなコードになるはずです。
link_to "show", @hoge ...
link_to "show", hoge_path(@hoge)
link_to "show", [@hoge1, @hoge2, ... ] ...
link_to "index", hoges_path ...
link_to "index", hoge1_hoge2s_path ...
link_to "new", new_hoge_path ...
link_to の使い方がシンプルになりました。コードも短くなりました。
method: :deleteはどう考えるか?
scaffold すると、レコードの削除として、method: :delete のついたlink_toが付いてきます。
賛否両論あると思いますが、私はこれにも違和感があるので、基本的に使いません。
form_forかbutton_toで対応しています。
少しだけ余談ですが...
私のこの違和感とたどり着いたゴールを裏付けるために、githubのhtmlソースを読んだところ、
aタグ でpostしているところはありませんでした。
... 見落としてたらすいません。m(_ _)m
やっぱり、link_to で postするのは基本的にNGなんだと、確信しました。
githubのhtmlソース、読みやすかったなあ。。。
というわけで、
細かい所もRailの上から外れないようにしたほうがいいよ。
というのを実感したお話でした。