class ActiveRecord::Error

def default_options


Return user options with default options.
def default_options
  options.reverse_merge :scope => [:activerecord, :errors],
                        :model => @base.class.human_name,
                        :attribute => @base.class.human_attribute_name(attribute.to_s),
                        :value => value
end

def full_message

def full_message
  attribute.to_s == 'base' ? message : generate_full_message(default_options)
end

def generate_full_message(options = {})

blank: This title is screwed!
title:
full_messages:
errors:
activerecord:
en:
# config/locales/en.yml

end
validates_presence_of :title, :message => :"title.blank"
class Article < ActiveRecord::Base
# app/models/article.rb

any particular validation:
validates_* class macro level one can customize the full_message format for
Because the message key used by a validation can be overwritten on the

key (such as validates_presence_of) can be stored to :"activerecord.errors.full_messages.blank".
E.g. the full_message format for any validation that uses :blank as a message
storing a translation for :"activerecord.errors.full_messages.[message_key]".
Additionally one can specify a validation specific error message format by

translation for the key :"activerecord.errors.full_messages.format".
One can specify locale specific default full_message format by storing it as a
The default full_message format for any locale is "%{attribute} %{message}".

Wraps an error message into a full_message format.
def generate_full_message(options = {})
  keys = [
    :"full_messages.#{@message}",
    :'full_messages.format',
    '%{attribute} %{message}'
  ]
  options.merge!(:default => keys, :message => self.message)
  I18n.translate(keys.shift, options)
end

def generate_message(options = {})


  • any default you provided through the +options+ hash (in the activerecord.errors scope)

  • activerecord.errors.messages.blank

  • activerecord.errors.models.user.blank

  • activerecord.errors.models.user.attributes.title.blank

  • activerecord.errors.models.admin.blank

  • activerecord.errors.models.admin.attributes.title.blank



    1. error +message+ for the title +attribute+, it looks for these translations:
      hasn't been found. Say you have class Admin < User; end and you wanted the translation for the :blank
      When using inheritence in your models, it will check all the inherited models too, but only if the model itself

      translated attribute name and the value are available for interpolation.
      default message (e.g. activerecord.errors.messages.MESSAGE). The translated model name,
      it's looked up in models.MODEL.MESSAGE and if that is not there it returns the translation of the
      Error messages are first looked up in models.MODEL.attributes.ATTRIBUTE.MESSAGE, if it's not there,
      Translates an error message in it's default scope (activerecord.errrors.messages).
    def generate_message(options = {})
      keys = @base.class.self_and_descendants_from_active_record.map do |klass|
        [ :"models.#{klass.name.underscore}.attributes.#{attribute}.#{@message}",
          :"models.#{klass.name.underscore}.#{@message}" ]
      end.flatten
      keys << options.delete(:default)
      keys << :"messages.#{@message}"
      keys << @message if @message.is_a?(String)
      keys << @type unless @type == @message
      keys.compact!
      options.merge!(:default => keys)
      I18n.translate(keys.shift, options)
    end

    def initialize(base, attribute, type = nil, options = {})

    def initialize(base, attribute, type = nil, options = {})
      self.base      = base
      self.attribute = attribute
      self.type      = type || :invalid
      self.options   = options
      self.message   = options.delete(:message) || self.type
    end

    def message

    def message
      # When type is a string, it means that we do not have to do a lookup, because
      # the user already sent the "final" message.
      type.is_a?(String) ? type : generate_message(default_options)
    end

    def value

    def value
      @base.respond_to?(attribute) ? @base.send(attribute) : nil
    end