Rails 3.0.0.beta4 をいじっているときのこと。。。
nested_attributes を使って親モデルと子モデルを同時に編集する際、error_messages_for を使ってバリデーションのエラーメッセージを吐き出してるんですが、なぜか子モデルのエラーだけがローカライズされない。
例:
class User < ActiveRecord::Base has_many :posts accepts_nested_attributes_for :posts validates_presence_of :name end class User < ActiveRecord::Base belongs_to :user validates_presence_of :title endで、
Posts title は必須です 名前は必須ですみたいに出力されてしまう。
運よくAnton Bangratzさんがパッチを書いてくれていた。Anton さんありがとうー!!
でも、パッチするのは嫌だったので、config/initializer/errors_i18n.rb と適当なファイルを作って、下記のように。。。
ActiveModel::Errors.module_eval do def full_messages full_messages = [] each do |attribute, messages| messages = Array.wrap(messages) next if messages.empty? if attribute == :base messages.each {|m| full_messages << m } else # attr_name = attribute.to_s.gsub('.', '_').humanize attr_name = convert_name(attribute.to_s) attr_name ||= attribute.to_s.gsub('.', '_').humanize attr_name = @base.class.human_attribute_name(attribute, :default => attr_name) options = { :default => "%{attribute} %{message}", :attribute => attr_name } messages.each do |m| full_messages << I18n.t(:"errors.format", options.merge(:message => m)) end end end full_messages end def convert_name(name) default = nil if name =~ /(.+)\.(.+)/ base_name = $1 attribute = $2 base = ActiveSupport::Dependencies.constantize(base_name.camelize) if (base.respond_to? :model_name) default = "#{base.model_name.human} #{base.human_attribute_name(attribute.to_sym, :default => attribute.humanize)}" end end default end end因みに、ActiveModel::Errors::ClassMethods.module_eval do では Name Error になった。なぜだ?