Rails6 のちょい足しな新機能を試す110（TranslationHelper#translate default オプション編）

# はじめに

Rails 6 に追加された新機能を試す第110段。 今回は、`TranslationHelper#translate`  `default` オプション編です。
Rails 6 では、 `TranslationHelper#translate` の `default` オプションで指定された値が Hash の場合に、その Hash が返されるようになりました。

Ruby 2.6.5, Rails 6.0.1 で確認しました。（Rails 6.0.0 時点で修正されています。）

```shell
$ rails --version
Rails 6.0.1
```

今回は、適切な使い道を思いつけませんでした。
で、言語 (locale) 毎に数字をカンマ区切りで表示するだけの、Railsアプリケーションを作って試してみることにします。

# Rails プロジェクトを作成する

```shell
$ rails new rails_sandbox
$ cd rails_sandbox
```

# Controller と View を作る

今回は、数字を表示するための NumbersController と index ページを作成します。


```shell
$ bin/rails g controller Numbers index
```

# Helper メソッドを作成する

`locale_number_with_delimiter` メソッドを作成します。
引数は、 数字と locale です。
default_number_format メソッドをコールして、locale に対するデフォルトフォーマットを決定します。
`TranslationHelper#translate` メソッド (`t` メソッド)を使って、 `number.format` を取得し、取得できなかった場合のために、default を指定します。
ここが、今回の確認ポイントになります。
`number_with_delimiter` メソッドで数字を変換します。


```ruby:app/helpers/numbers_helper.rb
module NumbersHelper
  def locale_number_with_delimiter(number, locale)
    default = default_number_format(locale)

    format = t('number.format', locale: locale, default: default) # ここがちょい足し機能
    number_with_delimiter(number, format)
  end

  private

  def default_number_format(locale)
    case locale
    when :en, :ja
      { delimiter: ',', separator: '.' }
    when :de, :it
      { delimiter: '.', separator: ',' }
    when :sv
      { delimiter: ' ', separator: ',' }
    when :ruby
      { delimiter: '_', separator: '.' }
    else
      { delimiter: ',', separator: '.' }
    end
  end
end
```

# Controller を修正する

`NumbersController` の `index` メソッドで、 `@locales` と `@number` を設定します。

```ruby:app/controllers/numbers_controller.rb
class NumbersController < ApplicationController
  def index
    @locales = %i[en ja de it sv ruby]
    @number = 10000.5
  end
end
```

# View を修正する

View では、 Language(Locale) と数字を表形式で表示します。

```ruby:app/views/numbers/index.html.erb
<h1>Numbers#index</h1>
<table>
  <thead>
    <tr>
      <th>
        Language
      </th>
      <th>
        Number
      </th>
    </tr>
  </thead>
  <tbody>
    <% @locales.each do |locale| %>
      <tr>
        <td><%= locale %></td>
        <td><%= locale_number_with_delimiter(@number, locale) %></td>
      </tr>
    <% end %>
  </tbody>
</table>
```

# config/application.rb を修正する

動作確認目的なので、locale のエラーが出ないように、 `config/application.rb` に、 `I18n.enforce_available_locales = false` を追加します。

```
module App
  class Application < Rails::Application
    ...
    I18n.enforce_available_locales = false
  end
end
```

# rails server を実行してブラウザで表示する

`rails server` を実行してブラウザで表示すると、それぞれの Language(locale) に合わせた数字の表示になっています。
![110_rails6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209941/49bf6ce6-c61e-a0b3-d563-a3865a5a3a85.png)


# Rails 5では

`TranslationHelper#translate` が default で指定した Hash を返さないため、NoMethodError になってしまい動作しません。
![110_rails5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209941/5529e9df-c445-f348-f67f-b51ba7ddf93d.png)

# 試したソース

試したソースは以下にあります。
https://github.com/suketa/rails_sandbox/tree/try110_translate_default

# 参考情報

* [Fix TranslationHelper#translate handling of Hash defaults](https://github.com/rails/rails/pull/36482)