Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Rails 5] joins calls ignore with_deleted scope #355

Closed
apolzon opened this issue Sep 16, 2016 · 8 comments
Closed

[Rails 5] joins calls ignore with_deleted scope #355

apolzon opened this issue Sep 16, 2016 · 8 comments
Labels

Comments

@apolzon
Copy link

apolzon commented Sep 16, 2016

I'm adding the with_deleted condition to a belongs_to association as so:

class Session < ActiveRecord::Base
  belongs_to :subject, -> { with_deleted }
end

This works properly when directly loading subject from a Session instance, but when executing a joins call, the deleted_at IS NULL is still included in the query:

SELECT \"sessions\".* FROM \"sessions\" INNER JOIN \"subjects\" ON \"subjects\".\"id\" = \"sessions\".\"subject_id\" AND \"subjects\".\"deleted_at\" IS NULL

I don't think that is the intended behavior, but if it is, it should probably be noted in the readme.

I don't believe this is a Rails bug, as I tried replacing the condition clause with something innocuous and the resulting sql output included the condition:

class Session < ActiveRecord::Base
  belongs_to :subject, -> { where(id: 1) }
end
"SELECT \"sessions\".* FROM \"sessions\" INNER JOIN \"subjects\" ON \"subjects\".\"id\" = \"sessions\".\"subject_id\" AND \"subjects\".\"id\" = 1 AND \"students_subjects\".\"deleted_at\" IS NULL"

I'm running paranoia v2.2.0.pre w/Rails 5.0.0.

@edwardmp
Copy link
Contributor

edwardmp commented Oct 23, 2016

I'm seeing similar behavior here on paranoia (2.2.0.pre) with rails (5.0.0.1)

class ParkingAction < ApplicationRecord
  belongs_to :numberplate, -> { with_deleted }
end

class Numberplate < ApplicationRecord
  acts_as_paranoid

  has_many :parking_actions
end

# returns record that references a numberplate that was soft deleted
ParkingAction.includes(:numberplate).where(numberplate_id: 210)

ParkingAction Load (0.4ms)  SELECT "parking_actions".* FROM "parking_actions" WHERE "parking_actions"."numberplate_id" = $1  [["numberplate_id", 210]]
Numberplate Load (0.5ms)  SELECT "numberplates".* FROM "numberplates" WHERE "numberplates"."id" = 210 ORDER BY plate

# doesn't return a record that references a numberplate that is deleted
ParkingAction.includes(:numberplate).where(numberplates: {id: 210})

SELECT "parking_actions"."id" AS t0_r0, "parking_actions"."begin" AS t0_r1, "parking_actions"."end" AS t0_r2, "parking_actions"."numberplate_id" AS t0_r3, "parking_actions"."created_at" AS t0_r4, "parking_actions"."updated_at" AS t0_r5, "parking_actions"."deleted_at" AS t0_r6, "numberplates"."id" AS t1_r0, "numberplates"."plate" AS t1_r1, "numberplates"."created_at" AS t1_r2, "numberplates"."updated_at" AS t1_r3, "numberplates"."plate_owner_id" AS t1_r4, "numberplates"."plate_owner_type" AS t1_r5, "numberplates"."deleted_at" AS t1_r6 FROM "parking_actions" LEFT OUTER JOIN "numberplates" ON "numberplates"."id" = "parking_actions"."numberplate_id" AND "numberplates"."deleted_at" IS NULL WHERE "numberplates"."id" = $1  [["id", 210]]

@edwardmp
Copy link
Contributor

edwardmp commented Oct 23, 2016

Seems to me that unscope(where: :deleted_at) does not remove the clause in associations. From the examples of unscope I have seen, It seems that this does actually be a rails bug.
Possibly related: rails/rails#22100

@gkop
Copy link

gkop commented Feb 13, 2017

Is this a dupe of #330 ?

Could both of these issues have been resolved by rails/rails#18109 which was merged a couple days ago?

@edwardmp
Copy link
Contributor

edwardmp commented Feb 14, 2017

@gkop
The fix was merged in 2016, and should be present in Rails v5.0.1. I don't see any merging activity in the last few days? I'm still experiencing this issue.

@edwardmp
Copy link
Contributor

edwardmp commented Feb 14, 2017

To give more context:

belongs_to :identifiable, -> { with_deleted }

This works as expected:
default_scope { preload(identifiable: { person: :company }).order(:begin) }

This doesn't remove the deleted_at where clause from identifiable, person and company:
default_scope { preload(identifiable: { person: :company }).unscope(:order).order(:begin) }

Results in the following query:
SELECT "parking_actions".* FROM "parking_actions" INNER JOIN "identifiables" ON "identifiables"."id" = "parking_actions"."identifiable_id" AND "identifiables"."deleted_at" IS NULL INNER JOIN "people" ON "people"."id" = "identifiables"."person_id" AND "people"."deleted_at" IS NULL INNER JOIN "companies" ON "companies"."id" = "people"."company_id" AND "companies"."deleted_at" IS NULL ORDER BY "parking_actions"."begin" ASC

@gkop
Copy link

gkop commented Feb 14, 2017

My mistake, I can still replicate too.

@edwardmp
Copy link
Contributor

So, I do actually think this is a Rails specific bug, not paranoia specific. Unscope doesn't unscope stuff from joined associations it seems.

@sgrif
Copy link

sgrif commented Jul 17, 2017

Should be fixed in rails/rails@5c71000

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants