aboutsummaryrefslogtreecommitdiffstats
path: root/activemodel/lib/active_model/errors.rb
diff options
context:
space:
mode:
authorRafael França <rafaelmfranca@gmail.com>2018-06-11 10:10:23 -0400
committerGitHub <noreply@github.com>2018-06-11 10:10:23 -0400
commitd3f659e5266a0154e252a05e63e806d4fac4c8e6 (patch)
tree71314ae0fd94d22911582c0b7e0fd9774ea03a5e /activemodel/lib/active_model/errors.rb
parent4eb1481c7f66a5c378b218676ece43b8ae13e553 (diff)
parent32513c4b356ed8b87b2c9caec6354b4b21cfc692 (diff)
downloadrails-d3f659e5266a0154e252a05e63e806d4fac4c8e6.tar.gz
rails-d3f659e5266a0154e252a05e63e806d4fac4c8e6.tar.bz2
rails-d3f659e5266a0154e252a05e63e806d4fac4c8e6.zip
Merge pull request #32956 from Shopify/i18n_activemodel_errors_full_message
Allow to override the full_message error format
Diffstat (limited to 'activemodel/lib/active_model/errors.rb')
-rw-r--r--activemodel/lib/active_model/errors.rb48
1 files changed, 46 insertions, 2 deletions
diff --git a/activemodel/lib/active_model/errors.rb b/activemodel/lib/active_model/errors.rb
index 275e3f1313..d583d48b54 100644
--- a/activemodel/lib/active_model/errors.rb
+++ b/activemodel/lib/active_model/errors.rb
@@ -62,6 +62,11 @@ module ActiveModel
CALLBACKS_OPTIONS = [:if, :unless, :on, :allow_nil, :allow_blank, :strict]
MESSAGE_OPTIONS = [:message]
+ class << self
+ attr_accessor :i18n_full_message # :nodoc:
+ end
+ self.i18n_full_message = false
+
attr_reader :messages, :details
# Pass in the instance of the object that is using the errors object.
@@ -364,12 +369,51 @@ module ActiveModel
# Returns a full message for a given attribute.
#
# person.errors.full_message(:name, 'is invalid') # => "Name is invalid"
+ #
+ # The `"%{attribute} %{message}"` error format can be overridden with either
+ #
+ # * <tt>activemodel.errors.models.person/contacts/addresses.attributes.street.format</tt>
+ # * <tt>activemodel.errors.models.person/contacts/addresses.format</tt>
+ # * <tt>activemodel.errors.models.person.attributes.name.format</tt>
+ # * <tt>activemodel.errors.models.person.format</tt>
+ # * <tt>errors.format</tt>
def full_message(attribute, message)
return message if attribute == :base
+
+ if self.class.i18n_full_message && @base.class.respond_to?(:i18n_scope)
+ parts = attribute.to_s.split(".")
+ attribute_name = parts.pop
+ namespace = parts.join("/") unless parts.empty?
+ attributes_scope = "#{@base.class.i18n_scope}.errors.models"
+
+ if namespace
+ defaults = @base.class.lookup_ancestors.map do |klass|
+ [
+ :"#{attributes_scope}.#{klass.model_name.i18n_key}/#{namespace}.attributes.#{attribute_name}.format",
+ :"#{attributes_scope}.#{klass.model_name.i18n_key}/#{namespace}.format",
+ ]
+ end
+ else
+ defaults = @base.class.lookup_ancestors.map do |klass|
+ [
+ :"#{attributes_scope}.#{klass.model_name.i18n_key}.attributes.#{attribute_name}.format",
+ :"#{attributes_scope}.#{klass.model_name.i18n_key}.format",
+ ]
+ end
+ end
+
+ defaults.flatten!
+ else
+ defaults = []
+ end
+
+ defaults << :"errors.format"
+ defaults << "%{attribute} %{message}"
+
attr_name = attribute.to_s.tr(".", "_").humanize
attr_name = @base.class.human_attribute_name(attribute, default: attr_name)
- I18n.t(:"errors.format",
- default: "%{attribute} %{message}",
+ I18n.t(defaults.shift,
+ default: defaults,
attribute: attr_name,
message: message)
end