diff --git a/activemodel/lib/active_model/errors.rb b/activemodel/lib/active_model/errors.rb
index 1431228..d76fd2e 100644
--- a/activemodel/lib/active_model/errors.rb
+++ b/activemodel/lib/active_model/errors.rb
@@ -170,6 +170,16 @@ module ActiveModel
self
end
+ # Represents a full error message
+ class ErrorMessage < String
+ attr_reader :full_message
+
+ def initialize(message, full_message)
+ super(message || full_message)
+ @full_message = full_message
+ end
+ end
+
# Adds +message+ to the error messages on +attribute+, which will be returned on a call to
# on(attribute) for the same attribute. More than one error can be added to the same
# +attribute+ in which case an array will be returned on a call to on(attribute).
@@ -180,12 +190,17 @@ module ActiveModel
def add(attribute, message = nil, options = {})
message ||= :invalid
+ full_message = options[:full_message]
+ message = full_message if full_message.is_a? Proc
+
if message.is_a?(Symbol)
message = generate_message(attribute, message, options.except(*CALLBACKS_OPTIONS))
elsif message.is_a?(Proc)
message = message.call
+ full_message &&= message
end
+ message &&= ErrorMessage.new(message, full_message) if full_message
self[attribute] << message
end
@@ -245,7 +260,8 @@ module ActiveModel
options = { :default => "%{attribute} %{message}", :attribute => attr_name }
messages.each do |m|
- full_messages << I18n.t(:"errors.format", options.merge(:message => m))
+ full_messages << ((m.respond_to?(:full_message) && m.full_message) ?
+ m.full_message : I18n.t(:"errors.format", options.merge(:message => m)))
end
end
end
@@ -280,6 +296,7 @@ module ActiveModel
#
def generate_message(attribute, type = :invalid, options = {})
type = options.delete(:message) if options[:message].is_a?(Symbol)
+ full_message = options.delete(:full_message)
if options[:default]
ActiveSupport::Deprecation.warn \
@@ -296,7 +313,7 @@ module ActiveModel
defaults << options.delete(:message)
defaults << :"#{@base.class.i18n_scope}.errors.messages.#{type}"
defaults << :"errors.attributes.#{attribute}.#{type}"
- defaults << :"errors.messages.#{type}"
+ defaults << :"errors.#{full_message ? 'full_' : ''}messages.#{type}"
defaults.compact!
defaults.flatten!