ActsAsParanoid / acts_as_paranoid

ActiveRecord plugin allowing you to hide and restore records without actually deleting them.
MIT License
1.46k stars 191 forks source link

with_deleted unscopes everything when joining through multiple associations #282

Open heaven opened 2 years ago

heaven commented 2 years ago

We have Subscriptions, Products, Prices, and AddOns.

class Payments::Subscription < ApplicationRecord
  has_many :subscription_addons,
    class_name: "Payments::SubscriptionAddon", inverse_of: :subscription, dependent: :destroy

  has_many :addons, class_name: "Payments::Product", through: :subscription_addons, source: :product
end

class Payments::SubscriptionAddon < ApplicationRecord
  belongs_to :price, -> { with_deleted },
    class_name: "Payments::Price", inverse_of: :subscription_addons

  has_one :product, class_name: "Payments::Product", through: :price
end

class Payments::Price < ApplicationRecord
  belongs_to :product, -> { with_deleted },
    class_name: "Payments::Product", inverse_of: :prices
end

When I access @subscription.subscription_addons everything is great and it returns only SubscriptionAddons where deleted_at is null.

But when I need to access @subscription.addons, the response also includes Products joined through already deleted SubscriptionAddons. In other words with_deleted that I apply to belongs_to :product/:price also applies to has_many :subscription_addons even thought it wasn't explicitly declared there. Basically, it unscopes where(::deleted_at) where it shouldn't.

kroehre commented 2 years ago

I just encountered this as well. @heaven were you able to find a workaround?

heaven commented 2 years ago

@kroehre nope and I don't think there is an easy fix, unfortunately. In my case, I simply stopped using acts_as_paranoid on SubscriptionAddon, which is just a :through model between Subscription and Price. This allowed me to work without with_deleted in associations. Also, building propper foreign key constraints and validations prevents deletions of a Price with active Subscriptions so this works somehow. Not as planned, though.

kroehre commented 2 years ago

~@mvz could this be related to https://github.com/ActsAsParanoid/acts_as_paranoid/pull/277 ?~ Issue persists after downgrading to 0.8.0