Tech Racho エンジニアの「?」を「!」に。
  • Ruby / Rails関連

Railsで1st、2nd、3rd、4thなどの序数を表示する方法(翻訳)

概要

原著者の許諾を得て翻訳・公開いたします。

日本語タイトルは内容に即したものにしました。

参考: §7.3 ordinalize -- Active Support コア拡張機能 - Railsガイド

なお、英語ロケールに設定されていないRailsアプリで、国際化用のロケールyamlファイルやフォールバックなどが適切に設定されていない場合は、ordinalizeordinalメソッドを呼び出すと"Translation missing: ja.number.nth.ordinalized"エラーになります。

参考: §3.6.6 config.i18n.fallbacks -- Rails アプリケーションの設定項目 - Railsガイド
参考: §3.2 訳文を与えて文字列を国際化する -- Rails 国際化(I18n)API - Railsガイド

また、ordinalizeordinalはゼロや負のIntegerには対応していますが、当然ながらFloatなどには対応していません。

Railsで1st、2nd、3rd、4thなどの序数を表示する方法(翻訳)

Railsアプリケーションを開発するときに、数字を人間が読みやすい形式で表示する必要が生じることがよくあります。たとえば、「1」や「42」だけではなく、「1st」や「42nd」のような序数を表示したい場合があります。Railsは、Active Support のコア拡張機能でそれ用の優れたソリューションを提供しています。

🔗 以下のように書くよりも

序数を完全に避ける。つまり基本的な文字列式展開で表示位置を工夫してしのぐ。

position = 1
"You finished in position #{position}"
# => "You finished in position 1"
position = 32
"You finished in position #{position}"
# => "You finished in position 1"

🔗 以下のように書こう

Rails組み込みのordinalメソッドやordinalizeメソッドを使う。

position = 1
"You finished in #{position.ordinalize} place"
# => "You finished in 1st place"
position = 11
"You finished in #{position.ordinalize} place"
# => "You finished in 11th place"
position = 22
"You finished in #{position.ordinalize} place"
# => "You finished in 22nd place"
position = 43
"You finished in #{position.ordinalize} place"
# => "You finished in 43rd place"

🔗 そうする理由

序数を使えば、特に「ランキング」「日付」「リスト」を扱うときのテキストが自然で読みやすいものになります。

コード例では英語の序数を示していますが、これらのメソッドは国際化に対応しているので他の言語にもローカライズできます(localizeは英国風に書けばlocaliseですね!)。

これはいつものように、Active Supportで拡張されたRailsツールキットの一部です。正しい序数サフィックスを決定し、アプリケーション全体で一貫した処理を確保するために独自のロジックをわざわざ記述して維持する必要はありません。

コード例で示したordinalizeは完全な序数(1st2ndなど)を返しますが、ordinalのようにサフィックスだけ(stndなど)を返すものもあります。

これらのメソッドをビューで頻繁に利用している場合や、特定のマークアップと組み合わせて利用している場合は、以下のようにロジックをヘルパーまたはデコレータに移動してビューを整理することを検討しましょう。

# app/helpers/number_helper.rb
module NumberHelper
  def wrapped_ordinal(number)
    tag.span(sanitize(number.to_s) << tag.span(number.ordinal, class: "ordinal"))
  end
end
<!-- whatever.html.erb -->
<%= wrapped_ordinal(1) %>
#=> "<span>1<span class=\"ordinal\">st</span></span>"

🔗 そうしない理由があるとすれば

Rails以外のRubyプロジェクトで作業している場合は、依存関係にactivesupport gemを追加する必要があります。その場合、Rubyのコアクラスで多くのメソッドにパッチが適用されることになります。

ただし、ほとんどのRailsアプリケーションではordinalordinalizeを使うのが最善の方法です。これらは現場のテストを経ていて効率もよく、車輪の再発明や読みにくい出力で我慢する必要がありません。

関連記事

Railsのblank?やpresent?は積極的に使おう(翻訳)

Rails: Active Supportの日付・時刻関連拡張はもっと活用すべき(翻訳)


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。