0

I am attempting to use the acts_as_paranoid gem with no luck. I have a Client model:

class Client < ActiveRecord::Base
    acts_as_paranoid
    has_many :purchases, dependent: :destroy
    has_many :payments, dependent: :destroy
end

and when I destroy a client with purchases and / or payments, and then attempt to recover, only the client is recovered, and not the associations.

> c = Client.find(231)
> c.payments.length
  Payment Load (0.6ms)  SELECT "payments".* FROM "payments" WHERE "payments"."client_id" = $1  [["client_id", 231]]
 => 1
> c.purchases.length
  Purchase Load (0.6ms)  SELECT "purchases".* FROM "purchases" WHERE "purchases"."client_id" = $1  [["client_id", 231]]
 => 1

If I delete the client:

> c.destroy

and run Client.only_deleted, I see the client that was just deleted. However, when I recover it and attempt to load the purchases or payments, there are none.

> Client.only_deleted.first.recover
> c = Client.find(231) # success
> c.payments.length # fail
  => 0

The associated records are not recovered. Am I missing something?

Jeremy Thomas
  • 6,240
  • 9
  • 47
  • 92

3 Answers3

2

I didn't realize I needed to run:

bin/rails generate migration AddDeletedAtToControllerName deleted_at:datetime:index

for all the associated models and add:

acts_as_paranoid

to the model's as well. After adding that, everything runs as expected

Jeremy Thomas
  • 6,240
  • 9
  • 47
  • 92
0

The reason why this happens is because acts_as_paranoid overwrites the destroy method for a ruby class. That means that associations with dependent: :destroy will act the same as they would if acts_as_paranoid wasn't defined on the class and would actually delete associated records.

So for every associated and dependent record that you want to prevent from being permanently deleted, yes, you will need to ensure that those records have acts_as_paranoid functionality as well.

ck-bamf
  • 27
  • 1
  • 5
  • Isn't this the same as what I wrote below? – Jeremy Thomas Mar 09 '18 at 12:27
  • It is! I just wanted to clarify the reason this is happening is because of the destroy callbacks. You might want to edit your response below to `AddDeletedAtToControllerName` to be `AddDeletedAtToModelName` though since that makes more sense to add a migration for a model instead of a controller. – ck-bamf Mar 09 '18 at 23:53
0

for all the associated models and add: act_as_paranoid

 class Purchase < ActiveRecord::Base
   acts_as_paranoid
 end
 
 class Payment < ActiveRecord::Base
   acts_as_paranoid
 end

In this case c = Client.find(231), c.destroy

It will works fine on deleting case, but when you recover that record then nothing will recover from associated as well. if you will remove dependent: :destroy from model where you want soft deletion using act_as_paranoid.

class Client < ActiveRecord::Base
  acts_as_paranoid
  has_many :purchases
  has_many :payments
end

this will works for you. Because destroy method for a ruby class. That means associations with dependent: :destroy will act the same as they would if acts_as_paranoid wasn't defined on the class and would actually delete associated records.