aboutsummaryrefslogtreecommitdiffstats
path: root/activemodel/lib/active_model/error.rb
diff options
context:
space:
mode:
Diffstat (limited to 'activemodel/lib/active_model/error.rb')
-rw-r--r--activemodel/lib/active_model/error.rb81
1 files changed, 81 insertions, 0 deletions
diff --git a/activemodel/lib/active_model/error.rb b/activemodel/lib/active_model/error.rb
new file mode 100644
index 0000000000..5a1298e27f
--- /dev/null
+++ b/activemodel/lib/active_model/error.rb
@@ -0,0 +1,81 @@
+# frozen_string_literal: true
+
+module ActiveModel
+ # == Active \Model \Error
+ #
+ # Represents one single error
+ class Error
+ CALLBACKS_OPTIONS = [:if, :unless, :on, :allow_nil, :allow_blank, :strict]
+ MESSAGE_OPTIONS = [:message]
+
+ def initialize(base, attribute, type = :invalid, **options)
+ @base = base
+ @attribute = attribute
+ @raw_type = type
+ @type = type || :invalid
+ @options = options
+ end
+
+ def initialize_dup(other)
+ @attribute = @attribute.dup
+ @raw_type = @raw_type.dup
+ @type = @type.dup
+ @options = @options.deep_dup
+ end
+
+ attr_reader :base, :attribute, :type, :raw_type, :options
+
+ def message
+ case raw_type
+ when Symbol
+ base.errors.generate_message(attribute, raw_type, options.except(*CALLBACKS_OPTIONS))
+ else
+ raw_type
+ end
+ end
+
+ def detail
+ { error: raw_type }.merge(options.except(*CALLBACKS_OPTIONS + MESSAGE_OPTIONS))
+ end
+
+ def full_message
+ base.errors.full_message(attribute, message)
+ end
+
+ # See if error matches provided +attribute+, +type+ and +options+.
+ def match?(attribute, type = nil, **options)
+ if @attribute != attribute || (type && @type != type)
+ return false
+ end
+
+ options.each do |key, value|
+ if @options[key] != value
+ return false
+ end
+ end
+
+ true
+ end
+
+ def strict_match?(attribute, type, **options)
+ return false unless match?(attribute, type, **options)
+
+ full_message == Error.new(@base, attribute, type, **options).full_message
+ end
+
+ def ==(other)
+ other.is_a?(self.class) && attributes_for_hash == other.attributes_for_hash
+ end
+ alias eql? ==
+
+ def hash
+ attributes_for_hash.hash
+ end
+
+ protected
+
+ def attributes_for_hash
+ [@base, @attribute, @raw_type, @options]
+ end
+ end
+end