web-dev-qa-db-ja.com

Ruby on Rails i18n-モデル内のカスタムメッセージを翻訳したい

Message句を使用して、その検証専用の特別なメッセージを表示する特別な検証を持つ属性があります。次に例を示します。

validates :email, presence:   true, length: { maximum: 60 },
                format:     { with: valid_email_regex, message: "is not a valid email address format." },
                uniqueness: { case_sensitive: false } 

ここでメッセージを翻訳したいのですが、どうすればいいのかわかりません。

メッセージ:t( "some_value_here")のように入力する例を見てきました。指定についてはわかりません。このメッセージのようなものを試しました:t(:bad_email)。何かを試すために、yamlファイルで次のことを行いました。

activemodel:
  errors:
    bad_email: "is not a valid email address format."

Railsアプリケーションにアクセスしようとすると、次のエラーが表示されました。

ActionView::Template::Error (undefined method `t' for #<Class:0x007fefc1b709e0>)

私はyamlファイルでもこれを試しました:

activemodel:
  errors:
    user:
      bad_email: "is not a valid email address format."

私はこれを一日中ずっと研究しています。私が見つけることができるのは、空白または空のような組み込みエラーハッシュを置き換えることです。カスタムエラーハッシュを作成してモデル内で置き換える方法はありますか?この時点で、tをコードどおりに動作させることはできません。私の希望は、問題がyamlファイルの設定方法にあることです。これを設定する方法のさまざまなバージョンを見てきました。これをactivemodelまたはactiverecordの下に置くべきかどうかはわかりません。私はactivemodelを想定しました。これは、カスタムメッセージが私が翻訳したい場所だからです。

任意の助けをいただければ幸いです。これは、アプリケーションの最初の翻訳を開始する前に理解する必要がある最後のピースです。

更新7/29/2013 7:30午後CDT

bgatesは、YAMLファイルでカスタムメッセージを受信するためにモデルファイルをセットアップする方法から非常に良いスタートをくれました。ただし、カスタムメッセージを見つけるには、yamlファイルで次のセットアップを行う必要がありました。

activerecord:
  errors: 
    models: 
      user: 
        attributes: 
          bio: 
            no_links: "cannot contain email addresses or website links (URLs)."
          email: 
            bad_email: "is not a valid email address format."
          username: 
            bad_username: "can only contain numbers and letters.  No special characters or spaces."

メッセージに記号を使用します。

_validates :email, presence:   true, length: { maximum: 60 },
            format:     { with: valid_email_regex, message: :bad_email },
            uniqueness: { case_sensitive: false } 
_

次に、yamlファイルで

_[lang]:
  activerecord:
    errors:
      messages:
        bad_email: "just ain't right"
_

このモデルに固有の翻訳がある場合、上記の一般的な翻訳をオーバーライドします。

_[lang]:
  activerecord:
    errors:
      models:
        model_name: # or namespace/model_name
          attributes:
            email:
              bad_email: "model-specific message for invalid email"
_

カスタム検証を記述する場合、add_error(:email, :bad_email)は上記のルックアップを行いますが、_errors[:email] << :bad_email_は行いません。

74
bgates

私はちょうどこれをすべて調べて、 カスタムバリデーターのレールガイド あまりにもハードコードされていることを発見しました...あなたが尋ねたとおりではありませんが、ここに投稿していますが、Qタイトルは完全に適合します(これが私の問題についてこの投稿を読んだ理由です)。

I18nメッセージを使用したカスタム検証:

validate :something_custom?, if: :some_trigger_condition

def something_custom?
  if some_error_condition
    errors.add(:some_field_key, :some_custom_msg)
  end
end

# en.yml
activerecord: 
  errors:
    models:
      some_model:
        some_custom_msg: "This is i18n controlled. yay!"
21
oma

これに対する解決策はカスタムである必要はありません。 format検証メッセージは、すでに:invalidシンボルにマップされています。無効な翻訳のみを設定する必要があります。

en:
  activerecord:
    errors:
      models:
        some_model:
          attributes:
            email:
              invalid: "FOO"

リファレンス: http://edgeguides.rubyonrails.org/i18n.html#error-message-interpolation

2
BookOfGreg

完全な例を挙げます。

モデルをきれいにするために、can完全に新しいディレクトリ-app/validationsにカスタム検証ヘルパーメソッドを作成します。これはRailsによって自動ロードされます。

time_validator.rbにあるファイルapp/validations/time_validator.rbを呼び出します

私のファイルには、ユーザーが入力した時間を検証する次のコードがあります-実際には時間時間です。

# frozen_string_literal: true

class TimeValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    Time.parse(value).strftime('%H:%M')
  rescue ArgumentError 
    record.errors.add(attribute, :invalid_time)
  end
end

カスタムActiveRecord検証の作成に関する詳細を読むことができます here

私たちの主な関心事はrecord.errors行です。 attributeはモデル内の列であり、:attributeではなくattributeであることに注意してください。

:invalid_timeは、ロケールファイルから翻訳されたコンテンツを取得するキーです。私の場合、これはenファイルです。

en
  activerecord:
    errors:
      models:
        home:
          attributes:
            check_in_time:
              invalid_time: Please enter valid time
            check_out_time:
              invalid_time: Please enter valid time

次に、homeモデルで:

validates :check_in_time, time: { allow_blank: true }
validates :check_out_time, time: { allow_blank: true }

timeは自動的にクラスTimeValidatorにマップされ、その中のメソッドが実行されます。

これに違反した場合、ActiveRecordは列名のすぐ下にエラーをスローします。

お役に立てれば!

0
Ruto Collins