-
Notifications
You must be signed in to change notification settings - Fork 120
/
Copy pathform_response.rb
70 lines (57 loc) · 1.85 KB
/
form_response.rb
1
2
3
4
5
6
7
8
9
10
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
# frozen_string_literal: true
class FormResponse
attr_reader :errors, :extra, :serialize_error_details_only
alias_method :serialize_error_details_only?, :serialize_error_details_only
def initialize(success:, errors: {}, extra: {}, serialize_error_details_only: false)
@success = success
@errors = errors.is_a?(ActiveModel::Errors) ? errors.messages.to_hash : errors
@error_details = errors.details if errors.is_a?(ActiveModel::Errors)
@extra = extra
@serialize_error_details_only = serialize_error_details_only
end
def success?
@success
end
def to_h
hash = { success: success }
hash[:errors] = errors if !serialize_error_details_only?
hash[:error_details] = flatten_details(error_details) if error_details.present?
hash.merge!(extra)
hash
end
alias_method :to_hash, :to_h
def merge(other)
self.class.new(
success: success? && other.success?,
errors: errors.merge(other.errors, &method(:merge_arrays)),
extra: extra.merge(other.extra),
).tap do |merged_response|
own_details = error_details
other_details = other.instance_eval { error_details } if other.is_a?(self.class)
merged_response.instance_eval do
@error_details = Hash(own_details).merge(Hash(other_details), &method(:merge_arrays))
end
end
end
def first_error_message(key = nil)
return if errors.blank?
key ||= errors.keys.first
errors[key].first
end
def ==(other)
success? == other.success? &&
errors == other.errors &&
extra == other.extra
end
private
def merge_arrays(_key, first, second)
Array(first) + Array(second)
end
def flatten_details(details)
details.transform_values do |errors|
errors.map { |error| error[:type] || error[:error] }.index_with(true)
end
end
attr_reader :success
attr_accessor :error_details
end