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