Rails: number_to_humanメソッドの書式をカスタマイズするときのコツ(翻訳)
number_to_human
はRailsで重宝するビューヘルパーのひとつで、出力をカスタマイズするオプションが豊富にあります。以下の詳しいAPIドキュメントを読むと、柔軟なオプションが多数揃っていることがわかります。
参考: Rails API number_to_human
-- ActiveSupport::NumberHelper
例:
number_to_human(12_345) # => "12.3 Thousand"
number_to_human(1_234_567) # => "1.23 Million"
number_to_human(1_234_567_890) # => "1.23 Billion"
私たちのcoveragebook.comというアプリでは、小さなカードに桁数の大きい数値(カウント)をSNS風に表示したいと考えています。
ここで出力したい数値フォーマットは以下のとおりです。
1_234 # => "1.2K"
12_345 # => "12.3K"
1_234_567 # => "1.3M"
1_234_567_890 # => "1.2B"
🔗 以下のように書くよりも
number_to_human
メソッドを使うたびに書式をカスタマイズする。
<%=
number_to_human(
1_234_567,
precision: 1,
significant: false,
round_mode: :down,
format: "%n%u",
units: {thousand: "K", million: "M", billion: "B"}
)
%>
🔗 以下のように書こう
config/locales/en.yml
で書式をカスタマイズする。
en:
number:
human:
decimal_units:
format: "%n%u"
units:
unit: ""
thousand: K
million: M
billion: B
trillion: T
quadrillion: Q
続いて以下のように書く。
number_to_human(1_234_567)
#=> "1.2M"
🔗 別の方法
以下のようなカスタムヘルパーを書いて使う。
def number_to_human_short(number)
return number_with_delimiter(number) if number < 10_000
number_to_human(
number,
precision: 1,
significant: false,
round_mode: :down,
format: "%n%u",
units: {
thousand: "K",
million: "M",
billion: "B",
trillion: "T"
}
)
end
続いて以下のように書く。
number_to_human_short(1_234_567)
#=> "1.2M"
これはMatt Swansonが以下で推奨している方法を基にしています(Chris OliverによるRailsWorldの発表で知りました)。
I don't think you can write this any cleaner than in Rails pic.twitter.com/pMFhli0izQ
— matt swanson 😈 (@_swanson) August 23, 2023
🔗 そうする理由
Railsは常識に沿ったデフォルト値を提供していますが、表示言語や数値の書式などについては自社独自の設計規約が存在することが多く、アプリの他の要素にも拡張される可能性が高いでしょう。
私たちのアプリでは数値を短縮形のみで表示することになっているため、YAMLのロケールファイルでヘルパーをカスタマイズしました。
書式をもっと柔軟にしたい場合や、複数の数値スタイルを使い分ける場合は、カスタムヘルパーを書くことをおすすめします。上の例では、10,000未満の数値は早期return
してそのまま表示するようになっています。つまり"9.9K"
ではなく"9,999"
と表示します。
🔗 そうしない理由があるとすれば
デフォルト設定で満足している場合や、カスタマイズを行う場所が1〜2箇所程度であれば、このようなレベルの間接処理は不要でしょう。
概要
元サイトの許諾を得て翻訳・公開いたします。
日本語タイトルは内容に即したものにしました。