From 7d09874a71ecceb929a99f914b703adc16d80e83 Mon Sep 17 00:00:00 2001 From: Martin Larochelle Date: Thu, 17 May 2018 08:39:31 -0400 Subject: Allow to override the full_message error format --- activemodel/lib/active_model/errors.rb | 43 ++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) (limited to 'activemodel/lib') diff --git a/activemodel/lib/active_model/errors.rb b/activemodel/lib/active_model/errors.rb index 275e3f1313..e813629855 100644 --- a/activemodel/lib/active_model/errors.rb +++ b/activemodel/lib/active_model/errors.rb @@ -364,12 +364,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 + # + # * activemodel.errors.models.person/contacts/addresses.attributes.street.format + # * activemodel.errors.models.person/contacts/addresses.format + # * activemodel.errors.models.person.attributes.name.format + # * activemodel.errors.models.person.format + # * errors.format def full_message(attribute, message) return message if attribute == :base + + if @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 -- cgit v1.2.3 From 32513c4b356ed8b87b2c9caec6354b4b21cfc692 Mon Sep 17 00:00:00 2001 From: Martin Larochelle Date: Tue, 22 May 2018 17:20:14 -0400 Subject: Add global config for config.active_model.i18n_full_message --- activemodel/lib/active_model/errors.rb | 7 ++++++- activemodel/lib/active_model/railtie.rb | 6 ++++++ 2 files changed, 12 insertions(+), 1 deletion(-) (limited to 'activemodel/lib') diff --git a/activemodel/lib/active_model/errors.rb b/activemodel/lib/active_model/errors.rb index e813629855..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. @@ -375,7 +380,7 @@ module ActiveModel def full_message(attribute, message) return message if attribute == :base - if @base.class.respond_to?(:i18n_scope) + 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? diff --git a/activemodel/lib/active_model/railtie.rb b/activemodel/lib/active_model/railtie.rb index a9cdabba00..0ed70bd473 100644 --- a/activemodel/lib/active_model/railtie.rb +++ b/activemodel/lib/active_model/railtie.rb @@ -7,8 +7,14 @@ module ActiveModel class Railtie < Rails::Railtie # :nodoc: config.eager_load_namespaces << ActiveModel + config.active_model = ActiveSupport::OrderedOptions.new + initializer "active_model.secure_password" do ActiveModel::SecurePassword.min_cost = Rails.env.test? end + + initializer "active_model.i18n_full_message" do + ActiveModel::Errors.i18n_full_message = config.active_model.delete(:i18n_full_message) || false + end end end -- cgit v1.2.3