Class: AdequateErrors::Error
- Inherits:
-
Object
- Object
- AdequateErrors::Error
- Defined in:
- lib/adequate_errors/error.rb
Overview
Represents one single error
Direct Known Subclasses
Instance Attribute Summary collapse
-
#attribute ⇒ Symbol
readonly
Attribute of the object which the error belongs to.
-
#base ⇒ ActiveModel::Base
readonly
The object which the error belongs to.
-
#options ⇒ Hash
readonly
Additional options.
-
#type ⇒ Symbol
readonly
Error’s type.
Instance Method Summary collapse
-
#initialize(base, attribute, type, options = {}) ⇒ Error
constructor
A new instance of Error.
-
#match?(params) ⇒ Boolean
Whether error matches the params.
-
#message ⇒ Object
Full message of the error.
Constructor Details
#initialize(base, attribute, type, options = {}) ⇒ Error
Returns a new instance of Error.
12 13 14 15 16 17 |
# File 'lib/adequate_errors/error.rb', line 12 def initialize(base, attribute, type, = {}) @base = base @attribute = attribute @type = type @options = end |
Instance Attribute Details
#attribute ⇒ Symbol (readonly)
Returns attribute of the object which the error belongs to.
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/adequate_errors/error.rb', line 11 class Error def initialize(base, attribute, type, = {}) @base = base @attribute = attribute @type = type @options = end attr_reader :base, :attribute, :type, :options # Full message of the error. # # === Key differences to Rails vanilla errors # # ==== 1. Flexible positioning of attribute name interpolation # # In Rails, errors' full messages are always prefixed with attribute name, # and if prefix is not wanted, developer often adds error to the `base' attribute instead. # This can be unreasonable in different languages or special business requirements. # # AdequateErrors leaves the attribute placement to the developer. # For each error message in the locale file, the %{attribute} indicates placement of the attribute. # The same error can have prefix in English, and be prefix-less in Russian. # If no prefix is needed, one should update the locale file accordingly, # # ==== 2. Message evaluated lazily # # In Rails, error message is evaluated during the `add` call. # AdequateErrors evaluates message lazily at `message` call instead, # so one can change message locale after model has been validated. # # === Order of I18n lookup: # # Error messages are first looked up in <tt>activemodel.adequate_errors.models.MODEL.attributes.ATTRIBUTE.MESSAGE</tt>, # if it's not there, it's looked up in <tt>activemodel.adequate_errors.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. # # 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 # <tt>class Admin < User; end</tt> and you wanted the translation for # the <tt>:blank</tt> error message for the <tt>title</tt> attribute, # it looks for these translations: # # * <tt>activemodel.adequate_errors.models.admin.attributes.title.blank</tt> # * <tt>activemodel.adequate_errors.models.admin.blank</tt> # * <tt>activemodel.adequate_errors.models.user.attributes.title.blank</tt> # * <tt>activemodel.adequate_errors.models.user.blank</tt> # * any default you provided through the +options+ hash (in the <tt>activemodel.adequate_errors</tt> scope) # * <tt>activemodel.adequate_errors.messages.blank</tt> # * <tt>adequate_errors.attributes.title.blank</tt> # * <tt>adequate_errors.messages.blank</tt> def if @options[:message].is_a?(Symbol) type = @options.delete(:message) else type = @type end if @base.class.respond_to?(:i18n_scope) i18n_scope = @base.class.i18n_scope.to_s defaults = @base.class.lookup_ancestors.flat_map do |klass| [ :"#{i18n_scope}.adequate_errors.models.#{klass.model_name.i18n_key}.attributes.#{attribute}.#{type}", :"#{i18n_scope}.adequate_errors.models.#{klass.model_name.i18n_key}.#{type}" ] end defaults << :"#{i18n_scope}.adequate_errors.messages.#{type}" else defaults = [] end defaults << :"adequate_errors.attributes.#{attribute}.#{type}" defaults << :"adequate_errors.messages.#{type}" key = defaults.shift defaults = @options.delete(:message) if @options[:message] value = (attribute != :base ? @base.send(:read_attribute_for_validation, attribute) : nil) = { default: defaults, model: @base.model_name.human, attribute: humanized_attribute, value: value, object: @base, exception_handler: ->(exception, locale, key, option) { rails_errors = @base.errors rails_errors.(@attribute, rails_errors.(@attribute, @type, @options)) } }.merge!(@options) I18n.translate(key, ) end # @param (see Errors#where) # @return [Boolean] whether error matches the params def match?(params) if params.key?(:attribute) && @attribute != params[:attribute] return false end if params.key?(:type) && @type != params[:type] return false end (params.keys - [:attribute, :type]).each do |key| if @options[key] != params[key] return false end end true end private def humanized_attribute default = @attribute.to_s.tr(".", "_").humanize @base.class.human_attribute_name(@attribute, default: default) end end |
#base ⇒ ActiveModel::Base (readonly)
Returns the object which the error belongs to.
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/adequate_errors/error.rb', line 11 class Error def initialize(base, attribute, type, = {}) @base = base @attribute = attribute @type = type @options = end attr_reader :base, :attribute, :type, :options # Full message of the error. # # === Key differences to Rails vanilla errors # # ==== 1. Flexible positioning of attribute name interpolation # # In Rails, errors' full messages are always prefixed with attribute name, # and if prefix is not wanted, developer often adds error to the `base' attribute instead. # This can be unreasonable in different languages or special business requirements. # # AdequateErrors leaves the attribute placement to the developer. # For each error message in the locale file, the %{attribute} indicates placement of the attribute. # The same error can have prefix in English, and be prefix-less in Russian. # If no prefix is needed, one should update the locale file accordingly, # # ==== 2. Message evaluated lazily # # In Rails, error message is evaluated during the `add` call. # AdequateErrors evaluates message lazily at `message` call instead, # so one can change message locale after model has been validated. # # === Order of I18n lookup: # # Error messages are first looked up in <tt>activemodel.adequate_errors.models.MODEL.attributes.ATTRIBUTE.MESSAGE</tt>, # if it's not there, it's looked up in <tt>activemodel.adequate_errors.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. # # 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 # <tt>class Admin < User; end</tt> and you wanted the translation for # the <tt>:blank</tt> error message for the <tt>title</tt> attribute, # it looks for these translations: # # * <tt>activemodel.adequate_errors.models.admin.attributes.title.blank</tt> # * <tt>activemodel.adequate_errors.models.admin.blank</tt> # * <tt>activemodel.adequate_errors.models.user.attributes.title.blank</tt> # * <tt>activemodel.adequate_errors.models.user.blank</tt> # * any default you provided through the +options+ hash (in the <tt>activemodel.adequate_errors</tt> scope) # * <tt>activemodel.adequate_errors.messages.blank</tt> # * <tt>adequate_errors.attributes.title.blank</tt> # * <tt>adequate_errors.messages.blank</tt> def if @options[:message].is_a?(Symbol) type = @options.delete(:message) else type = @type end if @base.class.respond_to?(:i18n_scope) i18n_scope = @base.class.i18n_scope.to_s defaults = @base.class.lookup_ancestors.flat_map do |klass| [ :"#{i18n_scope}.adequate_errors.models.#{klass.model_name.i18n_key}.attributes.#{attribute}.#{type}", :"#{i18n_scope}.adequate_errors.models.#{klass.model_name.i18n_key}.#{type}" ] end defaults << :"#{i18n_scope}.adequate_errors.messages.#{type}" else defaults = [] end defaults << :"adequate_errors.attributes.#{attribute}.#{type}" defaults << :"adequate_errors.messages.#{type}" key = defaults.shift defaults = @options.delete(:message) if @options[:message] value = (attribute != :base ? @base.send(:read_attribute_for_validation, attribute) : nil) = { default: defaults, model: @base.model_name.human, attribute: humanized_attribute, value: value, object: @base, exception_handler: ->(exception, locale, key, option) { rails_errors = @base.errors rails_errors.(@attribute, rails_errors.(@attribute, @type, @options)) } }.merge!(@options) I18n.translate(key, ) end # @param (see Errors#where) # @return [Boolean] whether error matches the params def match?(params) if params.key?(:attribute) && @attribute != params[:attribute] return false end if params.key?(:type) && @type != params[:type] return false end (params.keys - [:attribute, :type]).each do |key| if @options[key] != params[key] return false end end true end private def humanized_attribute default = @attribute.to_s.tr(".", "_").humanize @base.class.human_attribute_name(@attribute, default: default) end end |
#options ⇒ Hash (readonly)
Returns additional options.
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/adequate_errors/error.rb', line 11 class Error def initialize(base, attribute, type, = {}) @base = base @attribute = attribute @type = type @options = end attr_reader :base, :attribute, :type, :options # Full message of the error. # # === Key differences to Rails vanilla errors # # ==== 1. Flexible positioning of attribute name interpolation # # In Rails, errors' full messages are always prefixed with attribute name, # and if prefix is not wanted, developer often adds error to the `base' attribute instead. # This can be unreasonable in different languages or special business requirements. # # AdequateErrors leaves the attribute placement to the developer. # For each error message in the locale file, the %{attribute} indicates placement of the attribute. # The same error can have prefix in English, and be prefix-less in Russian. # If no prefix is needed, one should update the locale file accordingly, # # ==== 2. Message evaluated lazily # # In Rails, error message is evaluated during the `add` call. # AdequateErrors evaluates message lazily at `message` call instead, # so one can change message locale after model has been validated. # # === Order of I18n lookup: # # Error messages are first looked up in <tt>activemodel.adequate_errors.models.MODEL.attributes.ATTRIBUTE.MESSAGE</tt>, # if it's not there, it's looked up in <tt>activemodel.adequate_errors.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. # # 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 # <tt>class Admin < User; end</tt> and you wanted the translation for # the <tt>:blank</tt> error message for the <tt>title</tt> attribute, # it looks for these translations: # # * <tt>activemodel.adequate_errors.models.admin.attributes.title.blank</tt> # * <tt>activemodel.adequate_errors.models.admin.blank</tt> # * <tt>activemodel.adequate_errors.models.user.attributes.title.blank</tt> # * <tt>activemodel.adequate_errors.models.user.blank</tt> # * any default you provided through the +options+ hash (in the <tt>activemodel.adequate_errors</tt> scope) # * <tt>activemodel.adequate_errors.messages.blank</tt> # * <tt>adequate_errors.attributes.title.blank</tt> # * <tt>adequate_errors.messages.blank</tt> def if @options[:message].is_a?(Symbol) type = @options.delete(:message) else type = @type end if @base.class.respond_to?(:i18n_scope) i18n_scope = @base.class.i18n_scope.to_s defaults = @base.class.lookup_ancestors.flat_map do |klass| [ :"#{i18n_scope}.adequate_errors.models.#{klass.model_name.i18n_key}.attributes.#{attribute}.#{type}", :"#{i18n_scope}.adequate_errors.models.#{klass.model_name.i18n_key}.#{type}" ] end defaults << :"#{i18n_scope}.adequate_errors.messages.#{type}" else defaults = [] end defaults << :"adequate_errors.attributes.#{attribute}.#{type}" defaults << :"adequate_errors.messages.#{type}" key = defaults.shift defaults = @options.delete(:message) if @options[:message] value = (attribute != :base ? @base.send(:read_attribute_for_validation, attribute) : nil) = { default: defaults, model: @base.model_name.human, attribute: humanized_attribute, value: value, object: @base, exception_handler: ->(exception, locale, key, option) { rails_errors = @base.errors rails_errors.(@attribute, rails_errors.(@attribute, @type, @options)) } }.merge!(@options) I18n.translate(key, ) end # @param (see Errors#where) # @return [Boolean] whether error matches the params def match?(params) if params.key?(:attribute) && @attribute != params[:attribute] return false end if params.key?(:type) && @type != params[:type] return false end (params.keys - [:attribute, :type]).each do |key| if @options[key] != params[key] return false end end true end private def humanized_attribute default = @attribute.to_s.tr(".", "_").humanize @base.class.human_attribute_name(@attribute, default: default) end end |
#type ⇒ Symbol (readonly)
Returns error’s type.
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/adequate_errors/error.rb', line 11 class Error def initialize(base, attribute, type, = {}) @base = base @attribute = attribute @type = type @options = end attr_reader :base, :attribute, :type, :options # Full message of the error. # # === Key differences to Rails vanilla errors # # ==== 1. Flexible positioning of attribute name interpolation # # In Rails, errors' full messages are always prefixed with attribute name, # and if prefix is not wanted, developer often adds error to the `base' attribute instead. # This can be unreasonable in different languages or special business requirements. # # AdequateErrors leaves the attribute placement to the developer. # For each error message in the locale file, the %{attribute} indicates placement of the attribute. # The same error can have prefix in English, and be prefix-less in Russian. # If no prefix is needed, one should update the locale file accordingly, # # ==== 2. Message evaluated lazily # # In Rails, error message is evaluated during the `add` call. # AdequateErrors evaluates message lazily at `message` call instead, # so one can change message locale after model has been validated. # # === Order of I18n lookup: # # Error messages are first looked up in <tt>activemodel.adequate_errors.models.MODEL.attributes.ATTRIBUTE.MESSAGE</tt>, # if it's not there, it's looked up in <tt>activemodel.adequate_errors.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. # # 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 # <tt>class Admin < User; end</tt> and you wanted the translation for # the <tt>:blank</tt> error message for the <tt>title</tt> attribute, # it looks for these translations: # # * <tt>activemodel.adequate_errors.models.admin.attributes.title.blank</tt> # * <tt>activemodel.adequate_errors.models.admin.blank</tt> # * <tt>activemodel.adequate_errors.models.user.attributes.title.blank</tt> # * <tt>activemodel.adequate_errors.models.user.blank</tt> # * any default you provided through the +options+ hash (in the <tt>activemodel.adequate_errors</tt> scope) # * <tt>activemodel.adequate_errors.messages.blank</tt> # * <tt>adequate_errors.attributes.title.blank</tt> # * <tt>adequate_errors.messages.blank</tt> def if @options[:message].is_a?(Symbol) type = @options.delete(:message) else type = @type end if @base.class.respond_to?(:i18n_scope) i18n_scope = @base.class.i18n_scope.to_s defaults = @base.class.lookup_ancestors.flat_map do |klass| [ :"#{i18n_scope}.adequate_errors.models.#{klass.model_name.i18n_key}.attributes.#{attribute}.#{type}", :"#{i18n_scope}.adequate_errors.models.#{klass.model_name.i18n_key}.#{type}" ] end defaults << :"#{i18n_scope}.adequate_errors.messages.#{type}" else defaults = [] end defaults << :"adequate_errors.attributes.#{attribute}.#{type}" defaults << :"adequate_errors.messages.#{type}" key = defaults.shift defaults = @options.delete(:message) if @options[:message] value = (attribute != :base ? @base.send(:read_attribute_for_validation, attribute) : nil) = { default: defaults, model: @base.model_name.human, attribute: humanized_attribute, value: value, object: @base, exception_handler: ->(exception, locale, key, option) { rails_errors = @base.errors rails_errors.(@attribute, rails_errors.(@attribute, @type, @options)) } }.merge!(@options) I18n.translate(key, ) end # @param (see Errors#where) # @return [Boolean] whether error matches the params def match?(params) if params.key?(:attribute) && @attribute != params[:attribute] return false end if params.key?(:type) && @type != params[:type] return false end (params.keys - [:attribute, :type]).each do |key| if @options[key] != params[key] return false end end true end private def humanized_attribute default = @attribute.to_s.tr(".", "_").humanize @base.class.human_attribute_name(@attribute, default: default) end end |
Instance Method Details
#match?(params) ⇒ Boolean
Returns whether error matches the params.
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/adequate_errors/error.rb', line 107 def match?(params) if params.key?(:attribute) && @attribute != params[:attribute] return false end if params.key?(:type) && @type != params[:type] return false end (params.keys - [:attribute, :type]).each do |key| if @options[key] != params[key] return false end end true end |
#message ⇒ Object
Full message of the error.
Key differences to Rails vanilla errors
1. Flexible positioning of attribute name interpolation
In Rails, errors’ full messages are always prefixed with attribute name, and if prefix is not wanted, developer often adds error to the ‘base’ attribute instead. This can be unreasonable in different languages or special business requirements.
AdequateErrors leaves the attribute placement to the developer. For each error message in the locale file, the %#attribute indicates placement of the attribute. The same error can have prefix in English, and be prefix-less in Russian. If no prefix is needed, one should update the locale file accordingly,
2. Message evaluated lazily
In Rails, error message is evaluated during the ‘add` call. AdequateErrors evaluates message lazily at `message` call instead, so one can change message locale after model has been validated.
Order of I18n lookup:
Error messages are first looked up in activemodel.adequate_errors.models.MODEL.attributes.ATTRIBUTE.MESSAGE
, if it’s not there, it’s looked up in activemodel.adequate_errors.models.MODEL.MESSAGE
and if that is not there also, it returns the translation of the default message (e.g. activemodel.errors.messages.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 class Admin < User; end
and you wanted the translation for the :blank
error message for the title
attribute, it looks for these translations:
-
activemodel.adequate_errors.models.admin.attributes.title.blank
-
activemodel.adequate_errors.models.admin.blank
-
activemodel.adequate_errors.models.user.attributes.title.blank
-
activemodel.adequate_errors.models.user.blank
-
any default you provided through the
options
hash (in theactivemodel.adequate_errors
scope) -
activemodel.adequate_errors.messages.blank
-
adequate_errors.attributes.title.blank
-
adequate_errors.messages.blank
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/adequate_errors/error.rb', line 65 def if @options[:message].is_a?(Symbol) type = @options.delete(:message) else type = @type end if @base.class.respond_to?(:i18n_scope) i18n_scope = @base.class.i18n_scope.to_s defaults = @base.class.lookup_ancestors.flat_map do |klass| [ :"#{i18n_scope}.adequate_errors.models.#{klass.model_name.i18n_key}.attributes.#{attribute}.#{type}", :"#{i18n_scope}.adequate_errors.models.#{klass.model_name.i18n_key}.#{type}" ] end defaults << :"#{i18n_scope}.adequate_errors.messages.#{type}" else defaults = [] end defaults << :"adequate_errors.attributes.#{attribute}.#{type}" defaults << :"adequate_errors.messages.#{type}" key = defaults.shift defaults = @options.delete(:message) if @options[:message] value = (attribute != :base ? @base.send(:read_attribute_for_validation, attribute) : nil) = { default: defaults, model: @base.model_name.human, attribute: humanized_attribute, value: value, object: @base, exception_handler: ->(exception, locale, key, option) { rails_errors = @base.errors rails_errors.(@attribute, rails_errors.(@attribute, @type, @options)) } }.merge!(@options) I18n.translate(key, ) end |