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

Calling with_deleted unscopes all tables with has_many through #534

Open
scsmith opened this issue Jul 26, 2022 · 3 comments
Open

Calling with_deleted unscopes all tables with has_many through #534

scsmith opened this issue Jul 26, 2022 · 3 comments

Comments

@scsmith
Copy link

scsmith commented Jul 26, 2022

Assuming you have three models such as User, Posts, Comments all with acts_as_paranoid. If you have associations such as:

# User.rb
has_many :posts
has_many :comments, through: :posts

Calling user.comments would result in SQL with something like the following:

SELECT comments.* FROM comments
INNER JOIN posts ON comments.post_id = posts.id
INNER JOIN users on posts.user_id = users.id
WHERE comments.deleted_at IS NULL AND posts.deleted_at IS NULL AND users.deleted_at IS NULL
AND user.id = 1

calling users.comments.with_deleted will in turn call

unscope(where: :deleted_at)

this will result in all of the WHERE x.deleted_at IS NULL being removed.

I think that unscope should actually be restricted to the relationship that's being called, for example with_deleted here should actually call

unscope(where: { comments: :with_deleted})

Before I submit a pull request I'd like to guage interest in this as it would be quite a breaking change? Any thoughts / comments about how this could be achieved with the least upset to backwards compatibility?

@janko
Copy link

janko commented Apr 18, 2024

This is a huge issue for us, we've been bitten by this behavior many times, and we cannot seem to avoid making the same mistake. Why does with_deleted get applied to all tables in a joined association dataset, is it intended behavior? Because it sure does seem like a bug to me.

@scsmith
Copy link
Author

scsmith commented Apr 20, 2024

This is a huge issue for us, we've been bitten by this behavior many times, and we cannot seem to avoid making the same mistake. Why does with_deleted get applied to all tables in a joined association dataset, is it intended behavior? Because it sure does seem like a bug to me.

For what it's worth we added this to our application record and just renamed all of the with_deleted occurances:

  # This works similar to with_deleted from the paranoia gem.
  # However, this will restrict the query to only omit deleted_at
  # for the current table_name.
  def self.with_omitted(table_name = self.table_name)
    unscope(where: { table_name => :deleted_at })
  end

@janko
Copy link

janko commented Apr 22, 2024

Yeah, we did something similar after I posted this comment, we monkey-patched Paranoia's with_deleted:

class Paranoia::Query
  def with_deleted
    unscope where: { table_name.to_sym => paranoia_column }
  end
end

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

No branches or pull requests

2 participants