diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index df73eb4484be94117e6d5d1daaaa3e7ee2d21cb3..1f6ce385697a5fa747b0e1c3d82eb49795f7d9a2 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,3 +1,10 @@ +* Rails will now pass a custom validation context through to autosave associations + in order to validate child associations with the same context. + + Fixes #13854. + + *Eric Chahin*, *Aaron Nelson*, *Kevin Casey* + * Stringify all variable keys of mysql connection configuration. When the `sql_mode` variable for mysql adapters is set in the configuration diff --git a/activerecord/lib/active_record/autosave_association.rb b/activerecord/lib/active_record/autosave_association.rb index f149d8f1270e7886bf1679df114c5f1b3fbe824c..80cf7572dfedcb9b728df66caa9567b507b1f74d 100644 --- a/activerecord/lib/active_record/autosave_association.rb +++ b/activerecord/lib/active_record/autosave_association.rb @@ -304,7 +304,8 @@ def validate_collection_association(reflection) def association_valid?(reflection, record) return true if record.destroyed? || record.marked_for_destruction? - unless valid = record.valid? + validation_context = self.validation_context unless [:create, :update].include?(self.validation_context) + unless valid = record.valid?(validation_context) if reflection.options[:autosave] record.errors.each do |attribute, message| attribute = "#{reflection.name}.#{attribute}" diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb index 151edfc6a1efbc0df1219ffda6c39b6bec981bb1..d748e80695c2f2243f292270b63981c44e3df07b 100644 --- a/activerecord/test/cases/associations/has_many_associations_test.rb +++ b/activerecord/test/cases/associations/has_many_associations_test.rb @@ -26,6 +26,8 @@ require 'models/job' require 'models/college' require 'models/student' +require 'models/pirate' +require 'models/ship' class HasManyAssociationsTestForReorderWithJoinDependency < ActiveRecord::TestCase fixtures :authors, :posts, :comments @@ -1883,4 +1885,12 @@ def test_collection_association_with_private_kernel_method end end end + + test 'has_many_association passes context validation to validate children' do + pirate = FamousPirate.new + pirate.famous_ships << ship = FamousShip.new + assert_equal true, pirate.valid? + assert_equal false, pirate.valid?(:conference) + assert_equal "can't be blank", ship.errors[:name].first + end end diff --git a/activerecord/test/models/pirate.rb b/activerecord/test/models/pirate.rb index e472cf951dc79c245b7971f975729c3d364cb8e1..90a3c3ecee581c02819a6224a0e793c41c8cea3c 100644 --- a/activerecord/test/models/pirate.rb +++ b/activerecord/test/models/pirate.rb @@ -84,3 +84,9 @@ def log(record, callback) class DestructivePirate < Pirate has_one :dependent_ship, :class_name => 'Ship', :foreign_key => :pirate_id, :dependent => :destroy end + +class FamousPirate < ActiveRecord::Base + self.table_name = 'pirates' + has_many :famous_ships + validates_presence_of :catchphrase, on: :conference +end \ No newline at end of file diff --git a/activerecord/test/models/ship.rb b/activerecord/test/models/ship.rb index 3da031946f0d52226a4db747d185300302c54e7e..77a4728d0b396f2ea83aedbeeea29c5d7a1c4330 100644 --- a/activerecord/test/models/ship.rb +++ b/activerecord/test/models/ship.rb @@ -17,3 +17,9 @@ def cancel_save_callback_method false end end + +class FamousShip < ActiveRecord::Base + self.table_name = 'ships' + belongs_to :famous_pirate + validates_presence_of :name, on: :conference +end