mirror of https://github.com/rails/rails
Don't validate non dirty association targets
Fixes #36581. This fixes an issue where validations would return differently when a previously saved invalid association was loaded between calls: assert_equal true, squeak.valid? assert_equal true, squeak.mouse.present? assert_equal true, squeak.valid? Here the second assert would return Expected: true Actual: false Limiting validations to associations that would be normally saved (using autosave: true) due to changes means that loading invalid associated relations will not change the return value of the parent relations's `valid?` method.
This commit is contained in:
parent
88b91299f3
commit
6ea80b6103
|
@ -302,7 +302,7 @@ module ActiveRecord
|
|||
def validate_single_association(reflection)
|
||||
association = association_instance_get(reflection.name)
|
||||
record = association && association.reader
|
||||
association_valid?(reflection, record) if record
|
||||
association_valid?(reflection, record) if record && record.changed_for_autosave?
|
||||
end
|
||||
|
||||
# Validate the associated records if <tt>:validate</tt> or
|
||||
|
|
|
@ -13,12 +13,14 @@ require "models/developer"
|
|||
require "models/computer"
|
||||
require "models/invoice"
|
||||
require "models/line_item"
|
||||
require "models/mouse"
|
||||
require "models/order"
|
||||
require "models/parrot"
|
||||
require "models/pirate"
|
||||
require "models/project"
|
||||
require "models/ship"
|
||||
require "models/ship_part"
|
||||
require "models/squeak"
|
||||
require "models/tag"
|
||||
require "models/tagging"
|
||||
require "models/treasure"
|
||||
|
@ -386,6 +388,20 @@ class TestDefaultAutosaveAssociationOnABelongsToAssociation < ActiveRecord::Test
|
|||
|
||||
assert_predicate auditlog, :valid?
|
||||
end
|
||||
|
||||
def test_validation_does_not_validate_non_dirty_association_target
|
||||
mouse = Mouse.create!(name: "Will")
|
||||
Squeak.create!(mouse: mouse)
|
||||
|
||||
mouse.name = nil
|
||||
mouse.save! validate: false
|
||||
|
||||
squeak = Squeak.last
|
||||
|
||||
assert_equal true, squeak.valid?
|
||||
assert_equal true, squeak.mouse.present?
|
||||
assert_equal true, squeak.valid?
|
||||
end
|
||||
end
|
||||
|
||||
class TestDefaultAutosaveAssociationOnAHasManyAssociationWithAcceptsNestedAttributes < ActiveRecord::TestCase
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Mouse < ActiveRecord::Base
|
||||
has_many :squeaks, autosave: true
|
||||
validates :name, presence: true
|
||||
end
|
|
@ -0,0 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Squeak < ActiveRecord::Base
|
||||
belongs_to :mouse
|
||||
accepts_nested_attributes_for :mouse
|
||||
end
|
|
@ -563,6 +563,10 @@ ActiveRecord::Schema.define do
|
|||
t.string :type
|
||||
end
|
||||
|
||||
create_table :mice, force: true do |t|
|
||||
t.string :name
|
||||
end
|
||||
|
||||
create_table :movies, force: true, id: false do |t|
|
||||
t.primary_key :movieid
|
||||
t.string :name
|
||||
|
@ -843,6 +847,10 @@ ActiveRecord::Schema.define do
|
|||
end
|
||||
end
|
||||
|
||||
create_table :squeaks, force: true do |t|
|
||||
t.integer :mouse_id
|
||||
end
|
||||
|
||||
create_table :prisoners, force: true do |t|
|
||||
t.belongs_to :ship
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue