Search code examples
ruby-on-railsactiverecordhas-one

has_one relation automatically set nil if more than one


Give a two models, with a has_one association:

class ShopInfo
  belongs_to :shop
end

class Shop
  has_one :shop_info
end


s = Shop.create
ss1 = s.create_shop_info

In some other place of my code I do

ss2 = s.create_shop_info 

After this, ss1.shop_id is set to nil, so ss1 is now an orphan record.

Is there any way to remove previous records instead of set them to nil?


Solution

  • By default, the has_one association executes a nullify. Adding the dependent: :destroy solved the problem.

    class Shop
      has_one :shop_info, dependent: :destroy
    end
    

    Just if someone wants more info, the ActiveRecord code for has_one replacement record is this:

    https://github.com/rails/rails/blob/v4.2.6/activerecord/lib/active_record/associations/has_one_association.rb#L24-L51

    BUT if you add a dependent option in the association, executes the delete method as well:

    https://github.com/rails/rails/blob/v4.2.6/activerecord/lib/active_record/associations/has_one_association.rb#L7-L22