1

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?

scottysmalls
  • 1,231
  • 17
  • 23

2 Answers2

3

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

Community
  • 1
  • 1
Martin
  • 4,042
  • 2
  • 19
  • 29
  • I needed the functionality of delete so i had to look past destroy. dependent: :delete_all actually works though. I suppose i am just confused why using dependent: :delete_all has a different result from calling asset_items.delete_all. When calls i think would be the same have different results i worry i have an underlying problem somewhere. This is the correct answer though - it tells me why my delete_all call was just nulling the reference. i was not aware of delete_all(:delete_all) Cheers! – scottysmalls Apr 02 '17 at 06:17
0

use has_many :asset_items dependent: :destroy

lakhvir kumar
  • 255
  • 2
  • 10