mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
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
5 changed files with 37 additions and 1 deletions
|
@ -302,7 +302,7 @@ module ActiveRecord
|
||||||
def validate_single_association(reflection)
|
def validate_single_association(reflection)
|
||||||
association = association_instance_get(reflection.name)
|
association = association_instance_get(reflection.name)
|
||||||
record = association && association.reader
|
record = association && association.reader
|
||||||
association_valid?(reflection, record) if record
|
association_valid?(reflection, record) if record && record.changed_for_autosave?
|
||||||
end
|
end
|
||||||
|
|
||||||
# Validate the associated records if <tt>:validate</tt> or
|
# Validate the associated records if <tt>:validate</tt> or
|
||||||
|
|
|
@ -13,12 +13,14 @@ require "models/developer"
|
||||||
require "models/computer"
|
require "models/computer"
|
||||||
require "models/invoice"
|
require "models/invoice"
|
||||||
require "models/line_item"
|
require "models/line_item"
|
||||||
|
require "models/mouse"
|
||||||
require "models/order"
|
require "models/order"
|
||||||
require "models/parrot"
|
require "models/parrot"
|
||||||
require "models/pirate"
|
require "models/pirate"
|
||||||
require "models/project"
|
require "models/project"
|
||||||
require "models/ship"
|
require "models/ship"
|
||||||
require "models/ship_part"
|
require "models/ship_part"
|
||||||
|
require "models/squeak"
|
||||||
require "models/tag"
|
require "models/tag"
|
||||||
require "models/tagging"
|
require "models/tagging"
|
||||||
require "models/treasure"
|
require "models/treasure"
|
||||||
|
@ -386,6 +388,20 @@ class TestDefaultAutosaveAssociationOnABelongsToAssociation < ActiveRecord::Test
|
||||||
|
|
||||||
assert_predicate auditlog, :valid?
|
assert_predicate auditlog, :valid?
|
||||||
end
|
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
|
end
|
||||||
|
|
||||||
class TestDefaultAutosaveAssociationOnAHasManyAssociationWithAcceptsNestedAttributes < ActiveRecord::TestCase
|
class TestDefaultAutosaveAssociationOnAHasManyAssociationWithAcceptsNestedAttributes < ActiveRecord::TestCase
|
||||||
|
|
6
activerecord/test/models/mouse.rb
Normal file
6
activerecord/test/models/mouse.rb
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class Mouse < ActiveRecord::Base
|
||||||
|
has_many :squeaks, autosave: true
|
||||||
|
validates :name, presence: true
|
||||||
|
end
|
6
activerecord/test/models/squeak.rb
Normal file
6
activerecord/test/models/squeak.rb
Normal file
|
@ -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
|
t.string :type
|
||||||
end
|
end
|
||||||
|
|
||||||
|
create_table :mice, force: true do |t|
|
||||||
|
t.string :name
|
||||||
|
end
|
||||||
|
|
||||||
create_table :movies, force: true, id: false do |t|
|
create_table :movies, force: true, id: false do |t|
|
||||||
t.primary_key :movieid
|
t.primary_key :movieid
|
||||||
t.string :name
|
t.string :name
|
||||||
|
@ -843,6 +847,10 @@ ActiveRecord::Schema.define do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
create_table :squeaks, force: true do |t|
|
||||||
|
t.integer :mouse_id
|
||||||
|
end
|
||||||
|
|
||||||
create_table :prisoners, force: true do |t|
|
create_table :prisoners, force: true do |t|
|
||||||
t.belongs_to :ship
|
t.belongs_to :ship
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue