@@ -317,7 +317,12 @@ def nested_records_changed_for_autosave?
317
317
def validate_single_association ( reflection )
318
318
association = association_instance_get ( reflection . name )
319
319
record = association && association . reader
320
- association_valid? ( association , record ) if record && ( record . changed_for_autosave? || custom_validation_context? )
320
+ return unless record && ( record . changed_for_autosave? || custom_validation_context? )
321
+
322
+ inverse_belongs_to_association = inverse_belongs_to_association_for ( reflection , record )
323
+ return if inverse_belongs_to_association && inverse_belongs_to_association . updated?
324
+
325
+ association_valid? ( association , record )
321
326
end
322
327
323
328
# Validate the associated records if <tt>:validate</tt> or
@@ -429,36 +434,44 @@ def save_collection_association(reflection)
429
434
def save_has_one_association ( reflection )
430
435
association = association_instance_get ( reflection . name )
431
436
record = association && association . load_target
437
+ return unless record && !record . destroyed?
432
438
433
- if record && ! record . destroyed?
434
- autosave = reflection . options [ :autosave ]
439
+ inverse_belongs_to_association = inverse_belongs_to_association_for ( reflection , record )
440
+ return if inverse_belongs_to_association && inverse_belongs_to_association . updated?
435
441
436
- if autosave && record . marked_for_destruction?
437
- record . destroy
438
- elsif autosave != false
439
- primary_key = Array ( compute_primary_key ( reflection , self ) ) . map ( &:to_s )
440
- primary_key_value = primary_key . map { |key | _read_attribute ( key ) }
442
+ autosave = reflection . options [ :autosave ]
441
443
442
- if ( autosave && record . changed_for_autosave? ) || _record_changed? ( reflection , record , primary_key_value )
443
- unless reflection . through_reflection
444
- foreign_key = Array ( reflection . foreign_key )
445
- primary_key_foreign_key_pairs = primary_key . zip ( foreign_key )
444
+ if autosave && record . marked_for_destruction?
445
+ record . destroy
446
+ elsif autosave != false
447
+ primary_key = Array ( compute_primary_key ( reflection , self ) ) . map ( &:to_s )
448
+ primary_key_value = primary_key . map { |key | _read_attribute ( key ) }
446
449
447
- primary_key_foreign_key_pairs . each do |primary_key , foreign_key |
448
- association_id = _read_attribute ( primary_key )
449
- record [ foreign_key ] = association_id unless record [ foreign_key ] == association_id
450
- end
451
- association . set_inverse_instance ( record )
452
- end
450
+ if ( autosave && record . changed_for_autosave? ) || _record_changed? ( reflection , record , primary_key_value )
451
+ unless reflection . through_reflection
452
+ foreign_key = Array ( reflection . foreign_key )
453
+ primary_key_foreign_key_pairs = primary_key . zip ( foreign_key )
453
454
454
- saved = record . save ( validate : !autosave )
455
- raise ActiveRecord ::Rollback if !saved && autosave
456
- saved
455
+ primary_key_foreign_key_pairs . each do |primary_key , foreign_key |
456
+ association_id = _read_attribute ( primary_key )
457
+ record [ foreign_key ] = association_id unless record [ foreign_key ] == association_id
458
+ end
459
+ association . set_inverse_instance ( record )
457
460
end
461
+
462
+ saved = record . save ( validate : !autosave )
463
+ raise ActiveRecord ::Rollback if !saved && autosave
464
+ saved
458
465
end
459
466
end
460
467
end
461
468
469
+ def inverse_belongs_to_association_for ( reflection , record )
470
+ reflection . inverse_of &&
471
+ reflection . inverse_of . belongs_to? &&
472
+ record . association ( reflection . inverse_of . name )
473
+ end
474
+
462
475
# If the record is new or it has changed, returns true.
463
476
def _record_changed? ( reflection , record , key )
464
477
record . new_record? ||
@@ -480,7 +493,6 @@ def inverse_polymorphic_association_changed?(reflection, record)
480
493
return false unless reflection . inverse_of &.polymorphic?
481
494
482
495
class_name = record . _read_attribute ( reflection . inverse_of . foreign_type )
483
-
484
496
reflection . active_record != record . class . polymorphic_class_for ( class_name )
485
497
end
486
498
0 commit comments