@@ -20,9 +20,18 @@ def initialize_error_options(options, file = nil)
20
20
def add_error ( record , attribute , error_type , **errors_options )
21
21
return if record . errors . added? ( attribute , error_type )
22
22
23
+ error = record . errors . add ( attribute , error_type , **errors_options )
24
+
25
+ # Rails 8.1 introduced a new way to mark errors as nested
26
+ # https://github.com/igorkasyanchuk/active_storage_validations/issues/377
27
+ if Rails . gem_version >= Gem ::Version . new ( "8.1.0.alpha" )
28
+ # Mark errors as nested when they occur in a parent/child context
29
+ set_nested_error ( record , error ) if updating_through_parent? ( record )
30
+ end
31
+
23
32
# You can read https://api.rubyonrails.org/classes/ActiveModel/Errors.html#method-i-add
24
33
# to better understand how Rails model errors work
25
- record . errors . add ( attribute , error_type , ** errors_options )
34
+ error
26
35
end
27
36
28
37
private
@@ -36,5 +45,20 @@ def get_filename(file)
36
45
when Hash then file [ :filename ]
37
46
end . to_s
38
47
end
48
+
49
+ def updating_through_parent? ( record )
50
+ record . instance_variable_defined? ( :@marked_for_destruction ) ||
51
+ record . instance_variable_defined? ( :@_destroy ) ||
52
+ ( record . respond_to? ( :parent ) && record . parent . present? )
53
+ end
54
+
55
+ def set_nested_error ( record , error )
56
+ reflection = record . class . reflect_on_association ( :parent )
57
+
58
+ if reflection
59
+ association = record . association ( reflection . name )
60
+ record . errors . objects . append ( ActiveRecord ::Associations ::NestedError . new ( association , error ) )
61
+ end
62
+ end
39
63
end
40
64
end
0 commit comments