Created
May 14, 2011 02:18
-
-
Save AquaGeek/971657 to your computer and use it in GitHub Desktop.
Rails Lighthouse ticket #3768
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From 67eb80e72d8d4782334aabf3b120adf6fdca5cda Mon Sep 17 00:00:00 2001 | |
From: Rodrigo Rosenfeld Rosas <[email protected]> | |
Date: Thu, 25 Feb 2010 00:29:43 -0300 | |
Subject: [PATCH] Include support for :full_message option to validations. | |
--- | |
activemodel/lib/active_model/errors.rb | 54 +++++++++++++------ | |
.../lib/active_model/validations/acceptance.rb | 2 +- | |
.../lib/active_model/validations/confirmation.rb | 2 +- | |
.../lib/active_model/validations/exclusion.rb | 2 +- | |
activemodel/lib/active_model/validations/format.rb | 4 +- | |
.../lib/active_model/validations/inclusion.rb | 2 +- | |
activemodel/lib/active_model/validations/length.rb | 2 +- | |
.../lib/active_model/validations/numericality.rb | 6 +- | |
.../lib/active_model/validations/presence.rb | 2 +- | |
activemodel/lib/active_model/validator.rb | 5 ++ | |
10 files changed, 53 insertions(+), 28 deletions(-) | |
diff --git a/activemodel/lib/active_model/errors.rb b/activemodel/lib/active_model/errors.rb | |
index d832027..282e201 100644 | |
--- a/activemodel/lib/active_model/errors.rb | |
+++ b/activemodel/lib/active_model/errors.rb | |
@@ -161,20 +161,52 @@ module ActiveModel | |
end | |
end | |
- # Adds an error message (+messsage+) to the +attribute+, which will be returned on a call to <tt>on(attribute)</tt> | |
+ class ErrorMessage < String | |
+ attr_reader :options, :message | |
+ def initialize(options=nil) | |
+ if options.is_a? ErrorMessage | |
+ @options = options.options | |
+ return super(options.message) | |
+ end | |
+ @options = options.is_a?(Hash) ? options : {:message => options} | |
+ @message = @options[:full_message] || @options[:message] | |
+ super(@message.to_s) # in case of symbols... | |
+ end | |
+ | |
+ def full_message? | |
+ !!options[:full_message] rescue false # options could be nil for ErrorMessage.new.sub, for instance | |
+ end | |
+ end | |
+ | |
+ # Adds an error message (+message+) to the +attribute+, which will be returned on a call to <tt>on(attribute)</tt> | |
# for the same attribute and ensure that this error object returns false when asked if <tt>empty?</tt>. More than one | |
# error can be added to the same +attribute+ in which case an array will be returned on a call to <tt>on(attribute)</tt>. | |
- # If no +messsage+ is supplied, :invalid is assumed. | |
- # | |
+ # If no +message+ is supplied, :invalid is assumed. | |
+ # | |
# If +message+ is a Symbol, it will be translated, using the appropriate scope (see translate_error). | |
# If +message+ is a Proc, it will be called, allowing for things like Time.now to be used within an error | |
def add(attribute, message = nil, options = {}) | |
message ||= :invalid | |
+ full_message = (m=options[:default]).full_message? rescue false | |
+ options[:default] = m.message rescue m | |
message = generate_message(attribute, message, options) if message.is_a?(Symbol) | |
message = message.call if message.is_a?(Proc) | |
+ message = ErrorMessage.new :full_message => message if full_message | |
self[attribute] << message | |
end | |
+ def generate_full_message(attribute, predicate) | |
+ predicate = ErrorMessage.new(predicate) unless predicate.is_a? ErrorMessage | |
+ return (predicate.message.is_a?(Symbol) ? I18n.t(predicate.message) : predicate) if | |
+ attribute == :base or predicate.full_message? | |
+ | |
+ 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 } | |
+ | |
+ I18n.t(:"errors.format", options.merge(:message => predicate)) | |
+ end | |
+ | |
# Will add an error message to each of the attributes in +attributes+ that is empty. | |
def add_on_empty(attributes, custom_message = nil) | |
[attributes].flatten.each do |attribute| | |
@@ -206,20 +238,8 @@ module ActiveModel | |
full_messages = [] | |
each do |attribute, messages| | |
- messages = Array(messages) | |
- next if messages.empty? | |
- | |
- if attribute == :base | |
- messages.each {|m| full_messages << m } | |
- else | |
- 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 | |
+ messages = Array.wrap(messages) | |
+ messages.each {|m| full_messages << generate_full_message(attribute, m)} | |
end | |
full_messages | |
diff --git a/activemodel/lib/active_model/validations/acceptance.rb b/activemodel/lib/active_model/validations/acceptance.rb | |
index 0423fcd..d02a9e3 100644 | |
--- a/activemodel/lib/active_model/validations/acceptance.rb | |
+++ b/activemodel/lib/active_model/validations/acceptance.rb | |
@@ -7,7 +7,7 @@ module ActiveModel | |
def validate_each(record, attribute, value) | |
unless value == options[:accept] | |
- record.errors.add(attribute, :accepted, :default => options[:message]) | |
+ record.errors.add(attribute, :accepted, :default => message) | |
end | |
end | |
diff --git a/activemodel/lib/active_model/validations/confirmation.rb b/activemodel/lib/active_model/validations/confirmation.rb | |
index 8041d4b..37649ee 100644 | |
--- a/activemodel/lib/active_model/validations/confirmation.rb | |
+++ b/activemodel/lib/active_model/validations/confirmation.rb | |
@@ -4,7 +4,7 @@ module ActiveModel | |
def validate_each(record, attribute, value) | |
confirmed = record.send(:"#{attribute}_confirmation") | |
return if confirmed.nil? || value == confirmed | |
- record.errors.add(attribute, :confirmation, :default => options[:message]) | |
+ record.errors.add(attribute, :confirmation, :default => message) | |
end | |
def setup(klass) | |
diff --git a/activemodel/lib/active_model/validations/exclusion.rb b/activemodel/lib/active_model/validations/exclusion.rb | |
index 7ee718c..8bc2cf9 100644 | |
--- a/activemodel/lib/active_model/validations/exclusion.rb | |
+++ b/activemodel/lib/active_model/validations/exclusion.rb | |
@@ -8,7 +8,7 @@ module ActiveModel | |
def validate_each(record, attribute, value) | |
return unless options[:in].include?(value) | |
- record.errors.add(attribute, :exclusion, :default => options[:message], :value => value) | |
+ record.errors.add(attribute, :exclusion, :default => message, :value => value) | |
end | |
end | |
diff --git a/activemodel/lib/active_model/validations/format.rb b/activemodel/lib/active_model/validations/format.rb | |
index 9a9e7ec..f92d51b 100644 | |
--- a/activemodel/lib/active_model/validations/format.rb | |
+++ b/activemodel/lib/active_model/validations/format.rb | |
@@ -3,9 +3,9 @@ module ActiveModel | |
class FormatValidator < EachValidator | |
def validate_each(record, attribute, value) | |
if options[:with] && value.to_s !~ options[:with] | |
- record.errors.add(attribute, :invalid, :default => options[:message], :value => value) | |
+ record.errors.add(attribute, :invalid, :default => message, :value => value) | |
elsif options[:without] && value.to_s =~ options[:without] | |
- record.errors.add(attribute, :invalid, :default => options[:message], :value => value) | |
+ record.errors.add(attribute, :invalid, :default => message, :value => value) | |
end | |
end | |
diff --git a/activemodel/lib/active_model/validations/inclusion.rb b/activemodel/lib/active_model/validations/inclusion.rb | |
index 0c1334f..f8bcf73 100644 | |
--- a/activemodel/lib/active_model/validations/inclusion.rb | |
+++ b/activemodel/lib/active_model/validations/inclusion.rb | |
@@ -8,7 +8,7 @@ module ActiveModel | |
def validate_each(record, attribute, value) | |
return if options[:in].include?(value) | |
- record.errors.add(attribute, :inclusion, :default => options[:message], :value => value) | |
+ record.errors.add(attribute, :inclusion, :default => message, :value => value) | |
end | |
end | |
diff --git a/activemodel/lib/active_model/validations/length.rb b/activemodel/lib/active_model/validations/length.rb | |
index 9ceb754..c7ea251 100644 | |
--- a/activemodel/lib/active_model/validations/length.rb | |
+++ b/activemodel/lib/active_model/validations/length.rb | |
@@ -37,7 +37,7 @@ module ActiveModel | |
CHECKS.each do |key, validity_check| | |
next unless check_value = options[key] | |
- custom_message = options[:message] || options[MESSAGES[key]] | |
+ custom_message = message || options[MESSAGES[key]] | |
valid_value = if key == :maximum | |
value.nil? || value.size.send(validity_check, check_value) | |
diff --git a/activemodel/lib/active_model/validations/numericality.rb b/activemodel/lib/active_model/validations/numericality.rb | |
index c6d84c5..95e71b8 100644 | |
--- a/activemodel/lib/active_model/validations/numericality.rb | |
+++ b/activemodel/lib/active_model/validations/numericality.rb | |
@@ -26,7 +26,7 @@ module ActiveModel | |
return if options[:allow_nil] && raw_value.nil? | |
unless value = parse_raw_value(raw_value, options) | |
- record.errors.add(attr_name, :not_a_number, :value => raw_value, :default => options[:message]) | |
+ record.errors.add(attr_name, :not_a_number, :value => raw_value, :default => message) | |
return | |
end | |
@@ -34,14 +34,14 @@ module ActiveModel | |
case option | |
when :odd, :even | |
unless value.to_i.send(CHECKS[option]) | |
- record.errors.add(attr_name, option, :value => value, :default => options[:message]) | |
+ record.errors.add(attr_name, option, :value => value, :default => message) | |
end | |
else | |
option_value = option_value.call(record) if option_value.is_a?(Proc) | |
option_value = record.send(option_value) if option_value.is_a?(Symbol) | |
unless value.send(CHECKS[option], option_value) | |
- record.errors.add(attr_name, option, :default => options[:message], :value => value, :count => option_value) | |
+ record.errors.add(attr_name, option, :default => message, :value => value, :count => option_value) | |
end | |
end | |
end | |
diff --git a/activemodel/lib/active_model/validations/presence.rb b/activemodel/lib/active_model/validations/presence.rb | |
index 4a71cf7..3f4a846 100644 | |
--- a/activemodel/lib/active_model/validations/presence.rb | |
+++ b/activemodel/lib/active_model/validations/presence.rb | |
@@ -4,7 +4,7 @@ module ActiveModel | |
module Validations | |
class PresenceValidator < EachValidator | |
def validate(record) | |
- record.errors.add_on_blank(attributes, options[:message]) | |
+ record.errors.add_on_blank(attributes, message) | |
end | |
end | |
diff --git a/activemodel/lib/active_model/validator.rb b/activemodel/lib/active_model/validator.rb | |
index b61f0cb..48413b8 100644 | |
--- a/activemodel/lib/active_model/validator.rb | |
+++ b/activemodel/lib/active_model/validator.rb | |
@@ -158,6 +158,11 @@ module ActiveModel #:nodoc: | |
# ArgumentError when invalid options are supplied. | |
def check_validity! | |
end | |
+ | |
+ def message | |
+ return nil unless options[:full_message] || options[:message] | |
+ @message ||= Errors::ErrorMessage.new(options) | |
+ end | |
end | |
# BlockValidator is a special EachValidator which receives a block on initialization | |
-- | |
1.7.0 | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
# <tt>on(attribute)</tt> 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 <tt>on(attribute)</tt>. | |
@@ -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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/activemodel/lib/active_model/errors.rb b/activemodel/lib/active_model/errors.rb | |
index d832027..7a292d3 100644 | |
--- a/activemodel/lib/active_model/errors.rb | |
+++ b/activemodel/lib/active_model/errors.rb | |
@@ -161,34 +161,58 @@ module ActiveModel | |
end | |
end | |
- # Adds an error message (+messsage+) to the +attribute+, which will be returned on a call to <tt>on(attribute)</tt> | |
+ class FullErrorMessage < String | |
+ attr_reader :message | |
+ def initialize(message) | |
+ super((@message = message).to_s) # in case of symbols... | |
+ end | |
+ | |
+ def full_message? | |
+ true | |
+ end | |
+ end | |
+ | |
+ # Adds an error message (+message+) to the +attribute+, which will be returned on a call to <tt>on(attribute)</tt> | |
# for the same attribute and ensure that this error object returns false when asked if <tt>empty?</tt>. More than one | |
# error can be added to the same +attribute+ in which case an array will be returned on a call to <tt>on(attribute)</tt>. | |
- # If no +messsage+ is supplied, :invalid is assumed. | |
- # | |
+ # If no +message+ is supplied, :invalid is assumed. Pass +:full_message => true+ in the options for specifying | |
+ # it is the full message, so that the attribute is not prepended in <tt>full_messages</tt>. | |
+ # | |
# If +message+ is a Symbol, it will be translated, using the appropriate scope (see translate_error). | |
# If +message+ is a Proc, it will be called, allowing for things like Time.now to be used within an error | |
def add(attribute, message = nil, options = {}) | |
message ||= :invalid | |
message = generate_message(attribute, message, options) if message.is_a?(Symbol) | |
message = message.call if message.is_a?(Proc) | |
+ message = FullErrorMessage.new message if options[:full_message] | |
self[attribute] << message | |
end | |
+ def generate_full_message(attribute, message) | |
+ message = message.message if message.respond_to? :message | |
+ return (message.is_a?(Symbol) ? I18n.t(message) : message) if attribute == :base or (predicate.full_message? rescue false) | |
+ | |
+ 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 } | |
+ | |
+ I18n.t(:"errors.format", options.merge(:message => message)) | |
+ end | |
+ | |
# Will add an error message to each of the attributes in +attributes+ that is empty. | |
- def add_on_empty(attributes, custom_message = nil) | |
+ def add_on_empty(attributes, custom_message = nil, options = {}) | |
[attributes].flatten.each do |attribute| | |
value = @base.send(:read_attribute_for_validation, attribute) | |
is_empty = value.respond_to?(:empty?) ? value.empty? : false | |
- add(attribute, :empty, :default => custom_message) unless !value.nil? && !is_empty | |
+ add(attribute, :empty, options.merge(:default => custom_message)) unless !value.nil? && !is_empty | |
end | |
end | |
# Will add an error message to each of the attributes in +attributes+ that is blank (using Object#blank?). | |
- def add_on_blank(attributes, custom_message = nil) | |
+ def add_on_blank(attributes, custom_message = nil, options = {}) | |
[attributes].flatten.each do |attribute| | |
value = @base.send(:read_attribute_for_validation, attribute) | |
- add(attribute, :blank, :default => custom_message) if value.blank? | |
+ add(attribute, :blank, options.merge(:default => custom_message)) if value.blank? | |
end | |
end | |
@@ -206,20 +230,8 @@ module ActiveModel | |
full_messages = [] | |
each do |attribute, messages| | |
- messages = Array(messages) | |
- next if messages.empty? | |
- | |
- if attribute == :base | |
- messages.each {|m| full_messages << m } | |
- else | |
- 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 | |
+ messages = Array.wrap(messages) | |
+ messages.each {|m| full_messages << generate_full_message(attribute, m)} | |
end | |
full_messages | |
diff --git a/activemodel/lib/active_model/validations/acceptance.rb b/activemodel/lib/active_model/validations/acceptance.rb | |
index 0423fcd..dcb8ef5 100644 | |
--- a/activemodel/lib/active_model/validations/acceptance.rb | |
+++ b/activemodel/lib/active_model/validations/acceptance.rb | |
@@ -7,7 +7,7 @@ module ActiveModel | |
def validate_each(record, attribute, value) | |
unless value == options[:accept] | |
- record.errors.add(attribute, :accepted, :default => options[:message]) | |
+ add_error(record, attribute, :accepted) | |
end | |
end | |
diff --git a/activemodel/lib/active_model/validations/confirmation.rb b/activemodel/lib/active_model/validations/confirmation.rb | |
index 8041d4b..aa170f3 100644 | |
--- a/activemodel/lib/active_model/validations/confirmation.rb | |
+++ b/activemodel/lib/active_model/validations/confirmation.rb | |
@@ -4,7 +4,7 @@ module ActiveModel | |
def validate_each(record, attribute, value) | |
confirmed = record.send(:"#{attribute}_confirmation") | |
return if confirmed.nil? || value == confirmed | |
- record.errors.add(attribute, :confirmation, :default => options[:message]) | |
+ add_error(record, attribute, :confirmation) | |
end | |
def setup(klass) | |
diff --git a/activemodel/lib/active_model/validations/exclusion.rb b/activemodel/lib/active_model/validations/exclusion.rb | |
index 7ee718c..ebb67d8 100644 | |
--- a/activemodel/lib/active_model/validations/exclusion.rb | |
+++ b/activemodel/lib/active_model/validations/exclusion.rb | |
@@ -8,7 +8,7 @@ module ActiveModel | |
def validate_each(record, attribute, value) | |
return unless options[:in].include?(value) | |
- record.errors.add(attribute, :exclusion, :default => options[:message], :value => value) | |
+ add_error(record, attribute, :exclusion, :value => value) | |
end | |
end | |
diff --git a/activemodel/lib/active_model/validations/format.rb b/activemodel/lib/active_model/validations/format.rb | |
index 9a9e7ec..b8dc3ff 100644 | |
--- a/activemodel/lib/active_model/validations/format.rb | |
+++ b/activemodel/lib/active_model/validations/format.rb | |
@@ -2,11 +2,8 @@ module ActiveModel | |
module Validations | |
class FormatValidator < EachValidator | |
def validate_each(record, attribute, value) | |
- if options[:with] && value.to_s !~ options[:with] | |
- record.errors.add(attribute, :invalid, :default => options[:message], :value => value) | |
- elsif options[:without] && value.to_s =~ options[:without] | |
- record.errors.add(attribute, :invalid, :default => options[:message], :value => value) | |
- end | |
+ add_error(record, attribute, :invalid, :value => value) if | |
+ (options[:with] && value.to_s !~ options[:with]) or (options[:without] && value.to_s =~ options[:without]) | |
end | |
def check_validity! | |
diff --git a/activemodel/lib/active_model/validations/inclusion.rb b/activemodel/lib/active_model/validations/inclusion.rb | |
index 0c1334f..9f19d36 100644 | |
--- a/activemodel/lib/active_model/validations/inclusion.rb | |
+++ b/activemodel/lib/active_model/validations/inclusion.rb | |
@@ -8,7 +8,7 @@ module ActiveModel | |
def validate_each(record, attribute, value) | |
return if options[:in].include?(value) | |
- record.errors.add(attribute, :inclusion, :default => options[:message], :value => value) | |
+ add_error(record, attribute, :inclusion, :value => value) | |
end | |
end | |
diff --git a/activemodel/lib/active_model/validations/length.rb b/activemodel/lib/active_model/validations/length.rb | |
index 9ceb754..cdbae7f 100644 | |
--- a/activemodel/lib/active_model/validations/length.rb | |
+++ b/activemodel/lib/active_model/validations/length.rb | |
@@ -37,7 +37,7 @@ module ActiveModel | |
CHECKS.each do |key, validity_check| | |
next unless check_value = options[key] | |
- custom_message = options[:message] || options[MESSAGES[key]] | |
+ custom_message = message || options[MESSAGES[key]] | |
valid_value = if key == :maximum | |
value.nil? || value.size.send(validity_check, check_value) | |
@@ -46,7 +46,7 @@ module ActiveModel | |
end | |
next if valid_value | |
- record.errors.add(attribute, MESSAGES[key], :default => custom_message, :count => check_value) | |
+ add_error(record, attribute, MESSAGES[key], :default => custom_message, :count => check_value) | |
end | |
end | |
end | |
diff --git a/activemodel/lib/active_model/validations/numericality.rb b/activemodel/lib/active_model/validations/numericality.rb | |
index c6d84c5..99448b3 100644 | |
--- a/activemodel/lib/active_model/validations/numericality.rb | |
+++ b/activemodel/lib/active_model/validations/numericality.rb | |
@@ -26,7 +26,7 @@ module ActiveModel | |
return if options[:allow_nil] && raw_value.nil? | |
unless value = parse_raw_value(raw_value, options) | |
- record.errors.add(attr_name, :not_a_number, :value => raw_value, :default => options[:message]) | |
+ add_error(record, attr_name, :not_a_number, :value => raw_value) | |
return | |
end | |
@@ -34,14 +34,14 @@ module ActiveModel | |
case option | |
when :odd, :even | |
unless value.to_i.send(CHECKS[option]) | |
- record.errors.add(attr_name, option, :value => value, :default => options[:message]) | |
+ add_error(record, attr_name, option, :value => value) | |
end | |
else | |
option_value = option_value.call(record) if option_value.is_a?(Proc) | |
option_value = record.send(option_value) if option_value.is_a?(Symbol) | |
unless value.send(CHECKS[option], option_value) | |
- record.errors.add(attr_name, option, :default => options[:message], :value => value, :count => option_value) | |
+ add_error(record, attr_name, option, :value => value, :count => option_value) | |
end | |
end | |
end | |
diff --git a/activemodel/lib/active_model/validations/presence.rb b/activemodel/lib/active_model/validations/presence.rb | |
index 4a71cf7..624c88e 100644 | |
--- a/activemodel/lib/active_model/validations/presence.rb | |
+++ b/activemodel/lib/active_model/validations/presence.rb | |
@@ -4,7 +4,7 @@ module ActiveModel | |
module Validations | |
class PresenceValidator < EachValidator | |
def validate(record) | |
- record.errors.add_on_blank(attributes, options[:message]) | |
+ add_on_blank_error record | |
end | |
end | |
diff --git a/activemodel/lib/active_model/validator.rb b/activemodel/lib/active_model/validator.rb | |
index b61f0cb..57452de 100644 | |
--- a/activemodel/lib/active_model/validator.rb | |
+++ b/activemodel/lib/active_model/validator.rb | |
@@ -158,6 +158,21 @@ module ActiveModel #:nodoc: | |
# ArgumentError when invalid options are supplied. | |
def check_validity! | |
end | |
+ | |
+ def message | |
+ options[:full_message] || options[:message] | |
+ end | |
+ | |
+ def add_error(record, attribute, error_message, error_options={}) | |
+ opts = {:default => message} | |
+ opts.merge! :full_message => !!options[:full_message] if options[:full_message] | |
+ record.errors.add(attribute, error_message, opts.merge(error_options)) | |
+ end | |
+ | |
+ def add_on_blank_error(record) | |
+ opts = options[:full_message] ? {:full_message => true} : {} | |
+ record.errors.add_on_blank attributes, message, opts | |
+ end | |
end | |
# BlockValidator is a special EachValidator which receives a block on initialization |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/activemodel/lib/active_model/errors.rb b/activemodel/lib/active_model/errors.rb | |
index 1431228..96015d8 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 | |
# <tt>on(attribute)</tt> 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 <tt>on(attribute)</tt>. | |
@@ -178,15 +188,19 @@ module ActiveModel | |
# If +message+ is a symbol, it will be translated using the appropriate scope (see +translate_error+). | |
# If +message+ is a proc, it will be called, allowing for things like <tt>Time.now</tt> to be used within an error. | |
def add(attribute, message = nil, options = {}) | |
- message ||= :invalid | |
- | |
- if message.is_a?(Symbol) | |
- message = generate_message(attribute, message, options.except(*CALLBACKS_OPTIONS)) | |
- elsif message.is_a?(Proc) | |
- message = message.call | |
+ messages = {:message => message || :invalid, :full_message => options[:full_message]} | |
+ options = options.except(*CALLBACKS_OPTIONS) | |
+ | |
+ messages.each do |type, message| | |
+ if message.is_a? Symbol | |
+ messages[type] = generate_message(attribute, message, options) | |
+ elsif message.is_a? Proc | |
+ messages[type] = message.call | |
+ end | |
end | |
- self[attribute] << message | |
+ self[attribute] << (!messages[:full_message] ? messages[:message] : | |
+ ErrorMessage.new(messages[:message], messages[:full_message])) | |
end | |
# Will add an error message to each of the attributes in +attributes+ that is empty. | |
@@ -245,7 +259,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 +295,7 @@ module ActiveModel | |
# </ol> | |
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 +312,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! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/activemodel/lib/active_model/errors.rb b/activemodel/lib/active_model/errors.rb | |
index 1431228..efc7eb5 100644 | |
--- a/activemodel/lib/active_model/errors.rb | |
+++ b/activemodel/lib/active_model/errors.rb | |
@@ -170,23 +170,58 @@ module ActiveModel | |
self | |
end | |
+ # Represents a full error message. The full_message is available in <tt>full_message</tt> | |
+ # and <tt>to_s</tt> returns the +message+ given to constructor, or +full_message+ if +message+ is nil. | |
+ 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 | |
# <tt>on(attribute)</tt> 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 <tt>on(attribute)</tt>. | |
# If no +message+ is supplied, <tt>:invalid</tt> is assumed. | |
# | |
+ # If a <tt>:full_message</tt> option is specified, an ErrorMessage instance will be added to errors, | |
+ # which will be processed by <tt>full_messages</tt> as a full message (no concatenation with attribute names). | |
+ # | |
# If +message+ is a symbol, it will be translated using the appropriate scope (see +translate_error+). | |
- # If +message+ is a proc, it will be called, allowing for things like <tt>Time.now</tt> to be used within an error. | |
+ # If +message+ or +options[:message/:full_message]+ is a proc, it will be called with optional parameters, | |
+ # depending on proc arity, in the following order: instance (@base), +attribute+, +options+. | |
def add(attribute, message = nil, options = {}) | |
message ||= :invalid | |
+ proc_args = [@base, attribute, options] | |
- if message.is_a?(Symbol) | |
- message = generate_message(attribute, message, options.except(*CALLBACKS_OPTIONS)) | |
- elsif message.is_a?(Proc) | |
- message = message.call | |
+ if message.is_a? Proc | |
+ options = options.merge(:message => message) | |
+ ActiveSupport::Deprecation.warn \ | |
+ "ActiveModel::Errors#add(attributes, proc, options) has been deprecated.\n" + | |
+ "Instead of passing the proc to message, add it to options[:message] or options[:full_message] instead." | |
+ end | |
+ | |
+ message_options = options.except(:full_message, *CALLBACKS_OPTIONS) | |
+ messages = {}.tap{|m| m.merge! :message => message unless message.is_a? Symbol} | |
+ [:message, :full_message].each do |key| | |
+ messages[key] ||= options[key] | |
+ if (msg_proc = messages[key]).is_a?(Proc) | |
+ messages[key] = case msg_proc.arity | |
+ when 0: msg_proc.call | |
+ when -1: msg_proc.call(*proc_args) | |
+ else msg_proc.call(*proc_args[0..msg_proc.arity-1]) | |
+ end | |
+ elsif message.is_a?(Symbol) && ((key == :message) || messages[:full_message]) | |
+ opts = message_options | |
+ opts.merge! :message => messages[key] if messages[key] | |
+ messages[key] = generate_message attribute, message, opts #, key (temporarily disabled, to avoid changing the tests for now) | |
+ end | |
end | |
- self[attribute] << message | |
+ self[attribute] << (!messages[:full_message] ? messages[:message] : | |
+ ErrorMessage.new(messages[:message], messages[:full_message])) | |
end | |
# Will add an error message to each of the attributes in +attributes+ that is empty. | |
@@ -224,12 +259,12 @@ module ActiveModel | |
# | |
# class Company | |
# validates_presence_of :name, :address, :email | |
- # validates_length_of :name, :in => 5..30 | |
+ # validates_length_of :name, :in => 5..30, :full_message => 'You should specify a name between 5 and 30 characters' | |
# end | |
# | |
# company = Company.create(:address => '123 First St.') | |
# company.errors.full_messages # => | |
- # ["Name is too short (minimum is 5 characters)", "Name can't be blank", "Address can't be blank"] | |
+ # ["You should specify a name between 5 and 30 characters", "Name can't be blank", "Address can't be blank"] | |
def full_messages | |
full_messages = [] | |
@@ -245,7 +280,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 | |
@@ -259,8 +295,9 @@ module ActiveModel | |
# Error messages are first looked up in <tt>models.MODEL.attributes.ATTRIBUTE.MESSAGE</tt>, | |
# if it's not there, it's looked up in <tt>models.MODEL.MESSAGE</tt> and if that is not | |
# there also, it returns the translation of the default message | |
- # (e.g. <tt>activemodel.errors.messages.MESSAGE</tt>). The translated model name, | |
- # translated attribute name and the value are available for interpolation. | |
+ # (e.g. <tt>activemodel.errors.messages.MESSAGE</tt> or <tt>activemodel.errors.full_messages.MESSAGE</tt>, | |
+ # depending on the +translation_key+ param, which should be :message or :full_message). | |
+ # The translated model name, translated attribute name and the value are available for interpolation. | |
# | |
# When using inheritance in your models, it will check all the inherited | |
# models too, but only if the model itself hasn't been found. Say you have | |
@@ -278,7 +315,7 @@ module ActiveModel | |
# <li><tt>errors.attributes.title.blank</tt></li> | |
# <li><tt>errors.messages.blank</tt></li> | |
# </ol> | |
- def generate_message(attribute, type = :invalid, options = {}) | |
+ def generate_message(attribute, type = :invalid, options = {}, translation_key = :message) | |
type = options.delete(:message) if options[:message].is_a?(Symbol) | |
if options[:default] | |
@@ -296,7 +333,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.#{translation_key}s.#{type}" | |
defaults.compact! | |
defaults.flatten! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/activemodel/lib/active_model/errors.rb b/activemodel/lib/active_model/errors.rb | |
index 1431228..e2277fc 100644 | |
--- a/activemodel/lib/active_model/errors.rb | |
+++ b/activemodel/lib/active_model/errors.rb | |
@@ -170,6 +170,17 @@ 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 :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 | |
# <tt>on(attribute)</tt> 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 <tt>on(attribute)</tt>. | |
@@ -179,13 +190,17 @@ module ActiveModel | |
# If +message+ is a proc, it will be called, allowing for things like <tt>Time.now</tt> to be used within an error. | |
def add(attribute, message = nil, options = {}) | |
message ||= :invalid | |
+ full_message = options[:full_message] | |
if message.is_a?(Symbol) | |
- message = generate_message(attribute, message, options.except(*CALLBACKS_OPTIONS)) | |
+ options = options.except(*CALLBACKS_OPTIONS) | |
+ options[:message] = options.delete(:full_message) if full_message | |
+ message = generate_message(attribute, message, options) | |
elsif message.is_a?(Proc) | |
message = message.call | |
end | |
+ message = ErrorMessage.new(message, full_message) if message && 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 : I18n.t(:"errors.format", options.merge(:message => m))) | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/activemodel/lib/active_model/errors.rb b/activemodel/lib/active_model/errors.rb | |
index 1431228..8c71a5a 100644 | |
--- a/activemodel/lib/active_model/errors.rb | |
+++ b/activemodel/lib/active_model/errors.rb | |
@@ -170,6 +170,17 @@ 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 :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 | |
# <tt>on(attribute)</tt> 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 <tt>on(attribute)</tt>. | |
@@ -179,13 +190,18 @@ module ActiveModel | |
# If +message+ is a proc, it will be called, allowing for things like <tt>Time.now</tt> to be used within an error. | |
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)) | |
+ options = options.except(*CALLBACKS_OPTIONS) | |
+ options[:message] = options.delete(:full_message) if full_message | |
+ message = generate_message(attribute, message, options) | |
elsif message.is_a?(Proc) | |
message = message.call | |
end | |
+ message = ErrorMessage.new(message, full_message) if message && full_message | |
self[attribute] << message | |
end | |
@@ -245,7 +261,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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/activemodel/lib/active_model/errors.rb b/activemodel/lib/active_model/errors.rb | |
index 1431228..ecedd79 100644 | |
--- a/activemodel/lib/active_model/errors.rb | |
+++ b/activemodel/lib/active_model/errors.rb | |
@@ -170,6 +170,17 @@ 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 :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 | |
# <tt>on(attribute)</tt> 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 <tt>on(attribute)</tt>. | |
@@ -180,12 +191,19 @@ 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)) | |
+ options = options.except(*(CALLBACKS_OPTIONS + [:full_message])) | |
+ full_message = generate_message(attribute, message, options.merge(:message => full_message)) if full_message | |
+ message = generate_message(attribute, message, options) | |
elsif message.is_a?(Proc) | |
message = message.call | |
+ full_message = message if full_message | |
end | |
+ message = ErrorMessage.new(message, full_message) if (message && full_message) | |
self[attribute] << message | |
end | |
@@ -245,7 +263,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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/activemodel/lib/active_model/errors.rb b/activemodel/lib/active_model/errors.rb | |
index 1431228..abcf15c 100644 | |
--- a/activemodel/lib/active_model/errors.rb | |
+++ b/activemodel/lib/active_model/errors.rb | |
@@ -170,6 +170,17 @@ 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 :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 | |
# <tt>on(attribute)</tt> 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 <tt>on(attribute)</tt>. | |
@@ -180,12 +191,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)) | |
+ message = generate_message(attribute, message, options.except(*(CALLBACKS_OPTIONS + [:full_message]))) | |
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 +261,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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/activemodel/lib/active_model/errors.rb b/activemodel/lib/active_model/errors.rb | |
index 1431228..46b6a15 100644 | |
--- a/activemodel/lib/active_model/errors.rb | |
+++ b/activemodel/lib/active_model/errors.rb | |
@@ -170,6 +170,17 @@ 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 :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 | |
# <tt>on(attribute)</tt> 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 <tt>on(attribute)</tt>. | |
@@ -180,12 +191,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)) | |
+ message = generate_message(attribute, message, options.except(:full_message, *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 +261,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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/activemodel/lib/active_model/errors.rb b/activemodel/lib/active_model/errors.rb | |
index 1431228..304a010 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 | |
# <tt>on(attribute)</tt> 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 <tt>on(attribute)</tt>. | |
@@ -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)) | |
+ message = generate_message(attribute, message, options.except(:full_message, *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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
# <tt>on(attribute)</tt> 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 <tt>on(attribute)</tt>. | |
@@ -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 | |
# </ol> | |
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! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/activemodel/lib/active_model/errors.rb b/activemodel/lib/active_model/errors.rb | |
index 1431228..d8c8588 100644 | |
--- a/activemodel/lib/active_model/errors.rb | |
+++ b/activemodel/lib/active_model/errors.rb | |
@@ -170,6 +170,17 @@ 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 :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 | |
# <tt>on(attribute)</tt> 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 <tt>on(attribute)</tt>. | |
@@ -181,7 +192,10 @@ module ActiveModel | |
message ||= :invalid | |
if message.is_a?(Symbol) | |
- message = generate_message(attribute, message, options.except(*CALLBACKS_OPTIONS)) | |
+ options = options.except(*CALLBACKS_OPTIONS) | |
+ options[:message] = options.delete(:full_message) if full_message = options[:full_message] | |
+ message = generate_message(attribute, message, options) | |
+ message = ErrorMessage.new(message, full_message) if full_message | |
elsif message.is_a?(Proc) | |
message = message.call | |
end | |
@@ -245,7 +259,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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/activemodel/lib/active_model/errors.rb b/activemodel/lib/active_model/errors.rb | |
index 1431228..38549f5 100644 | |
--- a/activemodel/lib/active_model/errors.rb | |
+++ b/activemodel/lib/active_model/errors.rb | |
@@ -170,6 +170,17 @@ 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 :full_message | |
+ | |
+ def initialize(message, full_message) | |
+ super(message) | |
+ @full_message = full_message | |
+ end | |
+ end | |
+ | |
# Adds +message+ to the error messages on +attribute+, which will be returned on a call to | |
# <tt>on(attribute)</tt> 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 <tt>on(attribute)</tt>. | |
@@ -181,7 +192,10 @@ module ActiveModel | |
message ||= :invalid | |
if message.is_a?(Symbol) | |
- message = generate_message(attribute, message, options.except(*CALLBACKS_OPTIONS)) | |
+ options = options.except(*CALLBACKS_OPTIONS) | |
+ options[:message] = options.delete(:full_message) if full_message = options[:full_message] | |
+ message = generate_message(attribute, message, options) | |
+ message = ErrorMessage.new(message, full_message) if full_message | |
elsif message.is_a?(Proc) | |
message = message.call | |
end | |
@@ -245,7 +259,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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment