Rails で content_tag メソッドの代わりに tag メソッドに使うように促す cop を次の RuboCop Rails 2.6.0 で導入する予定です。
github.com
以下、bad ケースと good ケースをサンプルから抜粋します。
content_tag(:p, 'Hello world!')
content_tag(:br)
tag.p('Hello world!')
tag.br
2020年5月14日追記
第一引数に変数をとるケースについては、public_send
を使うくらいなら content_tag
を使う方が良さそうです。
以下は元記事として残していますが、これらの方法はとらない方が良いです。
PR の説明にあるように content_tag
はレガシーな API ということで、デフォルトで有効で良いと思っているものの、現状だと第一引数に変数をとる以下のケースに問題があります。
オートコレクトでコードが壊れることを防ぐため、以下の PR を問題解決のため開いていますが public_send
を使っているのが気にかかっている点です。
github.com
Case 1: NoMethodError
を防ぐ
元コード:
content_tag(name, 'foo', class: 'bar')
現状の auto-correct:
tag(name, 'foo', class: 'bar')
今後:
tag.public_send(name, 'foo', class: 'bar')
Case 2: symbolize_keys
を使って ArgumentError
を防ぐ
元コード:
content_tag(name, 'foo', {'class' => 'bar'})
現状の auto-correct:
tag.public_send(name, 'foo', {'class' => 'bar'})
今後:
symbolize_keys
を使って ArgumentError
を防ぐハックをしている。
引き渡されたハッシュのキーがすべてシンボルかどうか静的解析で検知がつらいための苦肉の策。
既存アプリケーションが壊れるのを防ぐためとはいえ、この解決はつらい。
tag.public_send(name, 'foo', {'class' => 'bar'}.symbolize_keys)
Case 3: ArgumentError
を防ぐため三項演算子を使っている
元コード:
content_tag(name, 'foo', options)
現状の auto-correct:
options = nil
tag.public_send(name, 'foo', options)
options
が nil のときに ArgumentError
です。
今後:
tag.public_send(name, 'foo', options ? options.symbolize_keys : {})
なかなか厳しいものがあるので、content_tag
の第一引数が変数の場合は無視するという対応も考えられるものの、もっと良い tag
への変換があれば教えてもらえると嬉しいです (知らないだけでもっと良い tag
メソッドへの置換方法がある?) 。