1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Fix strict loading on validations

We don't want strict loading to throw an error on validations since
those need to load the record in order to validate it.

This change check the owners's `validation_context`. If it's `nil` then
we know we're not currently validating an object in create/update. If
it's set then we're validating and want to skip raising for strict
loading.

Fixes: #40767
This commit is contained in:
eileencodes 2020-12-09 13:42:24 -05:00
parent ff0b9a47bd
commit bda9bc013b
No known key found for this signature in database
GPG key ID: BA5C575120BBE8DF
3 changed files with 29 additions and 2 deletions

View file

@ -211,11 +211,11 @@ module ActiveRecord
private
def find_target
if owner.strict_loading?
if owner.strict_loading? && owner.validation_context.nil?
Base.strict_loading_violation!(owner: owner.class, association: klass)
end
if reflection.strict_loading?
if reflection.strict_loading? && owner.validation_context.nil?
Base.strict_loading_violation!(owner: owner.class, association: reflection.name)
end

View file

@ -86,6 +86,27 @@ class StrictLoadingTest < ActiveRecord::TestCase
end
end
def test_strict_loading_is_ignored_in_validation_context
with_strict_loading_by_default(Developer) do
developer = Developer.first
assert_predicate developer, :strict_loading?
assert_nothing_raised do
AuditLogRequired.create! developer_id: developer.id, message: "i am a message"
end
end
end
def test_strict_loading_with_reflection_is_ignored_in_validation_context
with_strict_loading_by_default(Developer) do
developer = Developer.first
assert_predicate developer, :strict_loading?
developer.required_audit_logs.build(message: "I am message")
developer.save!
end
end
def test_preload_audit_logs_are_strict_loading_because_parent_is_strict_loading
developer = Developer.first

View file

@ -72,6 +72,7 @@ class Developer < ActiveRecord::Base
class_name: "SpecialProject"
has_many :audit_logs
has_many :required_audit_logs, class_name: "AuditLogRequired"
has_many :strict_loading_audit_logs, -> { strict_loading }, class_name: "AuditLog"
has_many :strict_loading_opt_audit_logs, strict_loading: true, class_name: "AuditLog"
has_many :contracts
@ -125,6 +126,11 @@ class AuditLog < ActiveRecord::Base
belongs_to :unvalidated_developer, class_name: "Developer"
end
class AuditLogRequired < ActiveRecord::Base
self.table_name = "audit_logs"
belongs_to :developer, required: true
end
class DeveloperWithBeforeDestroyRaise < ActiveRecord::Base
self.table_name = "developers"
has_and_belongs_to_many :projects, join_table: "developers_projects", foreign_key: "developer_id"