diff --git a/activemodel/lib/active_model/errors.rb b/activemodel/lib/active_model/errors.rb
index 1431228..a2c2554 100644
--- a/activemodel/lib/active_model/errors.rb
+++ b/activemodel/lib/active_model/errors.rb
@@ -170,6 +170,20 @@ module ActiveModel
self
end
+ # Represents an error message. Contains the model instance (+base+), the +attribute+ and the +options+
+ # passed to validators.
+ class ErrorMessage < String
+ attr_reader :base, :attribute, :options
+ def initialize(message, base, attribute, options)
+ super(message)
+ @base, @attribute, @options = base, attribute, options
+ end
+
+ def full_message?
+ @full_message ||= options.include? :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 +194,17 @@ module ActiveModel
def add(attribute, message = nil, options = {})
message ||= :invalid
+ fm = options[:full_message]
+ opts = fm ? options.merge(:message => fm) : options
+ opts.delete(:full_message) if fm
+
if message.is_a?(Symbol)
- message = generate_message(attribute, message, options.except(*CALLBACKS_OPTIONS))
+ message = generate_message(attribute, message, opts.except(*CALLBACKS_OPTIONS))
elsif message.is_a?(Proc)
message = message.call
end
+ message = ErrorMessage.new(message, @base, attribute, options) if message
self[attribute] << message
end
@@ -245,7 +264,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 : I18n.t(:"errors.format", options.merge(:message => m)))
end
end
end