パパエンジニアのアウトプット帳

30歳に突入した1児のパパエンジニアのブログ

dependent: :restrict_with_errorのI18n対応にちょっとつまずいた

dependent: :restrict_with_errorを利用した時に、エラーメッセージを日本語化しようとしてちょっと調べたのでメモとして残す。

ちなみに、dependentオプションについては下記がまとまってて分かりやすい。

qiita.com


例えば下記のようなモデルがあったとする。

class User < ActiveRecord::Base
  belongs_to :department
end

class Department < ActiveRecord::Base
  has_many :users, dependent: :restrict_with_error
end

restrict_with_errorのlocaleの書き方ははググればすぐ出てくるが、このrecordの部分が日本語にならなくて困った。。

[translation_ja.yml]
ja:
  activerecord:
    errors:
      messages:
        restrict_dependent_destroy:
          many: "%{record}が存在しているため削除できません。"

モデル名のI18nなので下記のように書けばいけると思っていたが、どうもusersと複数系になっているので違う(usersにもしてみたがダメ)

[translation_ja.yml]
  activerecord:
    models:
      user: "ユーザ"

コード見ていると下記のようになっている。

# File activerecord/lib/active_record/associations/has_many_association.rb, line 11
      def handle_dependency
        case options[:dependent]
        when :restrict_with_exception
          raise ActiveRecord::DeleteRestrictionError.new(reflection.name) unless empty?

        when :restrict_with_error
          unless empty?
            record = klass.human_attribute_name(reflection.name).downcase
            owner.errors.add(:base, :"restrict_dependent_destroy.many", record: record)
            false
          end

        else
          if options[:dependent] == :destroy
            # No point in executing the counter update since we're going to destroy the parent anyway
            load_target.each { |t| t.destroyed_by_association = reflection }
            destroy_all
          else
            delete_all
          end
        end
      end

whenのrestrict_with_error部分にklass.human_attribute_name(reflection.name).downcaseとある。

human_attribute_nameだと!?

なので下記のように対応したら日本語表示されました。

[translation_ja.yml]
  activerecord:
    attributes:
      user:
        users: ユーザ


なんか気持ち悪い。。。