Skip to content
  • Andy Stewart's avatar
    f206e934
    Fix destroy of has_one with multiple belongs_to · f206e934
    Andy Stewart authored
    Given a model with multiple `belongs_to` associations where the inverse
    associations are `has_one`s, and all associations have `dependent:
    :destroy`, destroying any of the `has_one` models should destroy the
    `belongs_to` model and all its associated `has_one` models.
    
    However this only worked from one end.  When destroying the
    "non-working" end, the `belongs_to` model was correctly destroyed but
    the other `has_one` end was not.
    
    Here is an example using `has_one :through`:
    
        class Left < ActiveRecord::Base
          has_one :middle, dependent: :destroy
          has_one :right, through: :middle
        end
    
        class Middle < ActiveRecord::Base
          belongs_to :left, dependent: :destroy
          belongs_to :right, dependent: :destroy
        end
    
        class Right < ActiveRecord::Base
          has_one :middle, dependent: :destroy
          has_one :left, through: :middle
        end
    
    In this example:
    
    - `right.destroy` correctly destroys its `middle` and its `left`;
    - `left.destroy` destroys its `middle` but not its `right`.
    
    The end which worked depended on the order of `belongs_to` statements in the
    `belongs_to` model.
    
    This commit ensures that the no matter which `has_one` model you destroy, all
    associated models are destroyed as expected.
    
    Fixes #50948.
    f206e934
    Fix destroy of has_one with multiple belongs_to
    Andy Stewart authored
    Given a model with multiple `belongs_to` associations where the inverse
    associations are `has_one`s, and all associations have `dependent:
    :destroy`, destroying any of the `has_one` models should destroy the
    `belongs_to` model and all its associated `has_one` models.
    
    However this only worked from one end.  When destroying the
    "non-working" end, the `belongs_to` model was correctly destroyed but
    the other `has_one` end was not.
    
    Here is an example using `has_one :through`:
    
        class Left < ActiveRecord::Base
          has_one :middle, dependent: :destroy
          has_one :right, through: :middle
        end
    
        class Middle < ActiveRecord::Base
          belongs_to :left, dependent: :destroy
          belongs_to :right, dependent: :destroy
        end
    
        class Right < ActiveRecord::Base
          has_one :middle, dependent: :destroy
          has_one :left, through: :middle
        end
    
    In this example:
    
    - `right.destroy` correctly destroys its `middle` and its `left`;
    - `left.destroy` destroys its `middle` but not its `right`.
    
    The end which worked depended on the order of `belongs_to` statements in the
    `belongs_to` model.
    
    This commit ensures that the no matter which `has_one` model you destroy, all
    associated models are destroyed as expected.
    
    Fixes #50948.
Loading