diff options
author | Rafael França <rafaelmfranca@gmail.com> | 2019-04-24 16:16:00 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-04-24 16:16:00 -0400 |
commit | d4d145a6795ee7f461ef86a07e73a1f13fdb8574 (patch) | |
tree | ed4780a32c4e78d9890db43e02499e1b2e25d907 /activemodel/lib/active_model/error.rb | |
parent | 9834be65655e8552d25633b7376ab0654a23875d (diff) | |
parent | 5e24c333505c3bab3c85d834ac985281f141709f (diff) | |
download | rails-d4d145a6795ee7f461ef86a07e73a1f13fdb8574.tar.gz rails-d4d145a6795ee7f461ef86a07e73a1f13fdb8574.tar.bz2 rails-d4d145a6795ee7f461ef86a07e73a1f13fdb8574.zip |
Merge pull request #32313 from lulalala/model_error_as_object
Model error as object
Diffstat (limited to 'activemodel/lib/active_model/error.rb')
-rw-r--r-- | activemodel/lib/active_model/error.rb | 81 |
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 |