5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【Ruby on Rails】Validationのエラーをカスタマイズ&I18nを使って多言語化対応する!

Last updated at Posted at 2019-10-13

今回成し遂げたいこと

  • Validationエラーをカスタマイズしたい!
  • ヘッダーのAccept-Languageを見て、エラーを英語と日本語で表示できるようにしたい!

前提

今回は、下記のようなAddressモデルがあると仮定して話をしていきます。addressをcreateするときに、カスタマイズしたエラー、さらにAccept-Languageja(または未指定)なら日本語エラー、enなら英語エラーを表示させることが目標です。

address.rb
class Address < ApplicationRecord
  validates :zip_code, format: { with: /\A[0-9]{3}-[0-9]{4}\z/ }
  validates :residence_name, length: maximum: 250
end

コントローラーのcreateメソッドはこんな感じ

addresses_controller.rb
class AddressesController < ApiApplicationController
  def create
    address = Address.new(address_params)
    address.save! #例外を発生させたいので!をつける

    hash = { message: I18n.t("addresses.address_registration_success"), data: address }
    render status: 200, json: { data: hash }
  end
end

また、今回はAPIを作っていると仮定し、返り値は全てJSONとします。

現時点でcreateメソッドを動かすと、zip codeがXXX-XXXXの形でないよresidence nameは10文字以下でないといけないよ、が英語で返ってきます。これを日本語化、さらにエラーメッセージをカスタマイズしていきます。

image.png

まずはモデルに直接書き込んでみる方法

日本語のエラー文だけで問題ないなら、validationにmessageというパラメターと表示したいメッセージを書いてあげるだけで大丈夫です。

address.rb
class Address < ApplicationRecord

  validates :user_id, uniqueness: true
  validates :zip_code, format: {with: /\A[0-9]{3}-[0-9]{4}\z/, message: "はXXX-XXXXのように記入してください (記入例:123-4567)" }
  validates :residence_name, length: { maximum: 10, message: "は10文字以内で入力してください" }
end

結果:カラム名だけ英語になっちゃう

でもカラム名が英語になっていますね。。。。ここも日本語にしてあげたい。その場合はI18n対応が必要です!

image.png

I18nとは?

I18nってなんぞやという方のために、Railsガイドの説明文です。
image.png

なんかごちゃごちゃしてよくわからん・・・・(読む気にもならない)。
とりあえず、アプリを日本語にも英語にも、その他ドイツ語とかフランス語とか、多言語に対応できるようにしよう!という機能です。

I18nを入れてみる

I18n用のGemをGemfileに追記して、bundle installします。

Gemfile
gem 'rails-i18n', '~> 5.1'

I18nのデフォルト設定をapplication.rbApplication Class内に追記します。

application.rb
config.i18n.default_locale = :ja #デフォルト言語は日本語にするよ設定
config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}').to_s] #言語変換表はここにあるよ設定
config.i18n.available_locales = %w(en ja) #変換表は日本語と英語があるよ

最後に、/config/localesの直下に、ja.ymlという名前のファイルを作成します。
このファイル内で、変換してほしい言葉を書き書きしていきます。

変換例はこんな感じ。

ja.yml
ja:
  activerecord:
    models:
      モデル名: "日本語モデル名"
    attributes:
      モデル名: 
        カラム名: "日本語カラム名"

なので今回は、addresszip_coderesidence_nameを日本語に変換したいので、下記のように入力していきます。
このymlファイル、インデントなどが間違っているとうまく動いてくれないので、気をつけてくださいね。

ja.yml
ja:
  activerecord:
    models:
      address: "住所"
    attributes:
      address: 
        zip_code: "郵便番号"
        residence_name: "建物名"

結果・・・日本語になった!!

image.png

でも英語でも日本語のエラーになっちゃう

今回は日本語のエラー文をmodelのvalidationの中に直接書き込んでいるので、Accept-Languageenにしても、日本語エラー文になっちゃう。

image.png

ということで、validationのエラーメッセージもI18nで日本語と英語を変換してくれるように修正していきます。まずは日本語のエラーメッセージをja.ymlファイルの中で用意します。

下記のようにすることでaddresses.zip_code_validationが呼ばれたら、"はXXX-XXXXのように記入してください (記入例:123-4567)"と表示する、という風に表示したいメッセージをカスタマイズできます。

ja.yml
ja:
  activerecord:
    models:
      モデル名: "日本語モデル名"
    attributes:
      モデル名: 
        カラム名: "日本語カラム名"
  addresses:
    zip_code_validation: "はXXX-XXXXのように記入してください (記入例:123-4567)"
    residence_name_validation: "は10文字以内で入力してください"

英語用のエラーメッセージも用意していきましょう。/config/localesの直下に、en.ymlファイルがあると思うので(なければ作成してね)、下記のように追記します。インデントには注意してくださいね。

en.yml
en:
  activerecord:
    models:
      address: "address"
    attributes:
      address: 
        zip_code: "zip code "
        residence_name: "residence name "
  addresses:
    zip_code_validation: "must be in XXX-XXXX format. (ex:123-4567)"
    residence_name_validation: "must be less than 10 length"

最後に、モデルを下記のように修正します。

address.rb
class Address < ApplicationRecord
  validates :zip_code, format: {with: /\A[0-9]{3}-[0-9]{4}\z/, message: I18n.t(:'addresses.zip_code_validation')}
  validates :residence_name, length: { maximum: 10, message: I18n.t(:'addresses.residence_name_validation') }
end

これで、下記の設定ができました。Accept-Languageを見て英語日本語どちらかのカスタマイズされたメッセージを表示してくれます。

  • zip_codeformatのバリデーションが通らなかった場合は、ymlファイルのaddresses.zip_code_validationのメッセージを表示
  • residence_namelengthのバリデーションが通らなかった場合は、ymlファイルのaddresses.residence_name_validationのメッセージを表示

結果

Accept-Languagejaの場合

全て日本語になった!!デフォルトはjaで設定しているのでAccept-Languageの指定がなければ日本語文が表示されます。
image.png

Accept-Languageenの場合

全て英語になったー!!!
image.png

まとめ

ということで、Railsでの多言語化対応と、それに伴うI18nの基本的な使い方の説明でした。
最初は「I18n!?!?名前からして難しそう・・・」って感じですが、慣れてしまえば簡単。

5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?