Skip to content

Commit dce145f

Browse files
committed
[Rails] Handle properly 8.1 ActiveRecord::Associations::NestedError change (#377)
1 parent 1beaa85 commit dce145f

File tree

2 files changed

+32
-2
lines changed

2 files changed

+32
-2
lines changed

lib/active_storage_validations/shared/asv_errorable.rb

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,18 @@ def initialize_error_options(options, file = nil)
2020
def add_error(record, attribute, error_type, **errors_options)
2121
return if record.errors.added?(attribute, error_type)
2222

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+
2332
# You can read https://api.rubyonrails.org/classes/ActiveModel/Errors.html#method-i-add
2433
# to better understand how Rails model errors work
25-
record.errors.add(attribute, error_type, **errors_options)
34+
error
2635
end
2736

2837
private
@@ -36,5 +45,20 @@ def get_filename(file)
3645
when Hash then file[:filename]
3746
end.to_s
3847
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
3963
end
4064
end

test/validators/integration/integration_test.rb

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,9 +169,15 @@
169169
parent_model.update!(child_attributes: { image: image_150x150_file })
170170
end
171171

172-
it "does not allow to save the parent model" do
172+
it "does not allow to update the parent model" do
173173
assert_equal false, subject
174174
end
175+
176+
it "adds the child model's error to the parent model's errors" do
177+
subject
178+
179+
assert parent_model.errors.any? { |e| e.type == :content_type_invalid }
180+
end
175181
end
176182
end
177183
end

0 commit comments

Comments
 (0)