scottysmalls
scottysmalls

Reputation: 1251

delete_all does not work while each do delete does

Intended functionality - delete all linked asset_items when an asset_line_item is deleted. (without using destroy, destroy_all). I am using postgres

With the following model:

class AssetLineItem < PurchaseLineItem

  has_many :asset_items
  ...

  after_destroy :destroy_cleanup

  private

  def destroy_cleanup
    asset_items.delete_all
  end
end

This results in the asset_items remaining, however all of their asset_line_item columns are set to null.

  def destroy_cleanup
    asset_items.each do |asset_item|
      asset_item.delete
    end
  end

replacing delete_all with the loop above however has the intended result of delete all associated asset_items.

Although I have working code, I'm curious what could cause delete_all to act in this way?

Upvotes: 1

Views: 571

Answers (2)

Martin
Martin

Reputation: 4222

Calling just delete_all on association just nullifies the reference. It is the same as delete_all(:nullify):

pry(main)> Booking.last.passengers.delete_all
  Booking Load (0.6ms)  SELECT  `bookings`.* FROM `bookings`  ORDER BY `bookings`.`id` DESC LIMIT 1
  SQL (2.8ms)  UPDATE `passengers` SET `passengers`.`booking_id` = NULL WHERE `passengers`.`booking_id` = 157
=> nil

You need to call delete_all(:delete_all) to actually delete associated records.

Here is docs.

Or to get desired effect you can add following line to your AssetLineItem model:

has_many :asset_items, dependent: :destroy

as lakhvir kumar mentioned.

Also your destroy_cleanup callback could be refactored to:

  def destroy_cleanup
    asset_items.map(&:delete)
  end

Here is some good links to the topic:

delete_all vs destroy_all?

Rails :dependent => :destroy VS :dependent => :delete_all

Upvotes: 3

lakhvir kumar
lakhvir kumar

Reputation: 265

use has_many :asset_items dependent: :destroy

Upvotes: 0

Related Questions