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

MONGOID-5785 allow named scopes to remove a default scope #5832

Merged
merged 1 commit into from
Jun 18, 2024

Conversation

jamis
Copy link
Contributor

@jamis jamis commented Jun 17, 2024

As currently implemented, named scopes are merged with the default scope (see here). This means you cannot declare a named scope that unsets any part of the default scope; if you try, the default scope will simply be merged back into it.

Merging the default scope is not necessary, because any scope you pass in will already be based on the default scope:

class Person
  include Mongoid::Document

  default_scope { where(deleted_at: nil) }
  scope :germans, -> { where(country: 'DE') }
end

Here, Person.germans will always use the default scope, even without it being merged in, because calling where will initialize a new Criteria object using that default scope. Merging the default scope is redundant.

However, because this has been this way for a very long time (basically since the feature was first introduced prior to 2014), we risk breaking code that inadvertently depends on this behavior. Thus, I've opted to put the fix behind a flag, which we can flip when we eventually release Mongoid 10.

@jamis jamis merged commit d58d8e1 into mongodb:master Jun 18, 2024
54 of 56 checks passed
@jamis jamis deleted the 5785-remove-scoping branch June 18, 2024 13:47
@johnnyshields
Copy link
Contributor

johnnyshields commented Jun 21, 2024

@jamis @comandeo-mongo please roll this back. This behavior should stay as-is with no feature flag or intention to change it.

The .unscoped method works perfectly in this case today. It is completely counter-intuitive that using a named scope would magically cause the default scope to disappear.

Further example of how this will break apps in all sorts of fun and exciting ways here:

https://jira.mongodb.org/browse/MONGOID-5785?focusedCommentId=6461746&focusedId=6461746&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-6461746

@johnnyshields
Copy link
Contributor

Correction: I misunderstood the change here. Since it's only calling ".unscoped" within a named scope it should be fine.

@stanley90
Copy link
Contributor

Hi, I'm a bit late to the party (was on vacation), just want to pinpoint that using unscoped does not solve the problem I described, because it removes everything, whereas I only want to remove a specific part of the default scope (paranoia, precisely). I'll take a closer look at this when I'm back at work. Thanks

@jamis
Copy link
Contributor Author

jamis commented Jun 26, 2024

@stanley90 -- thanks for chiming in. The PR includes tests that confirm correct behavior using unscoped, as well as with remove_scoping (see https://github.com/mongodb/mongoid/pull/5832/files#diff-d374f75265fac28314512810734ae94770db90759b5b05d5f76e546e01acecfaR1258-R1259). I'm confident it works correctly in both cases.

@stanley90
Copy link
Contributor

@jamis I patched the Scopable.define_scope_method in my project and confirm it does solve the problem. I'll keep the patch until I'm able to upgrade Mongoid 😀 Thanks

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

Successfully merging this pull request may close these issues.

4 participants