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

Keep current scope when calling roots #437

Merged
merged 1 commit into from
Jan 10, 2021

Conversation

p8
Copy link
Contributor

@p8 p8 commented Dec 5, 2020

6c5040c Fixed the Rails 6.1 deprecation warnings for inherited scoping by
making scopes explicit using Model.unscoped, or Model.default_scoped.

However the default_scoped method added to Model.nested_set_scope
broke calling roots on Relatable when the nested set is scoped:

bob = User.create!(name: 'Bob')
bobs_root = bob.categories.create(name: 'Root Category')
alice = User.create!(name: 'Alice')

# Alice has no categories so root should return nil
# Instead it returned bobs_root
assert_equal(nil, alice.categories.root)

Instead of using two separate class methods,
nested_set_scope_without_default_scope and nested_set_scope, that
apply the scope, we move the default_scoped and unscoped calls to
self.class.base_class. This fixes the roots scope and removes the
deprecation warnings.

Also see the Rails discussion:
rails/rails#41066 (comment)

Fixes: #436

@p8 p8 marked this pull request as draft December 5, 2020 10:24
@parndt
Copy link
Collaborator

parndt commented Jan 4, 2021

@p8 thanks for this; I take it that being marked as draft means it's not ready?

@p8
Copy link
Contributor Author

p8 commented Jan 4, 2021

@parndt Yes, I'm not sure this is the correct implementation. I'll create an issue in Rails to make sure.

@clwy-cn
Copy link

clwy-cn commented Jan 8, 2021

@parndt Please merge it。

@parndt
Copy link
Collaborator

parndt commented Jan 8, 2021

@parndt Please merge it。

@clwy-cn no, thanks... I'm waiting for @p8 to confirm, as it's their PR.

@p8 p8 force-pushed the fix-root-scope branch 2 times, most recently from f735acd to 2389a9e Compare January 9, 2021 16:01
@p8 p8 changed the title Use current_scope if available on Model.nested_set_scope Use scoping to reuse scopes in Model.nested_set_scope Jan 9, 2021
@p8
Copy link
Contributor Author

p8 commented Jan 9, 2021

I've created an issue in Rails: rails/rails#41066

@p8 p8 changed the title Use scoping to reuse scopes in Model.nested_set_scope Use current_scope if available on Model.nested_set_scope Jan 9, 2021
@p8 p8 force-pushed the fix-root-scope branch 3 times, most recently from 1bd0137 to ecce33c Compare January 10, 2021 09:55
@p8 p8 changed the title Use current_scope if available on Model.nested_set_scope Keep current scope when calling roots Jan 10, 2021
6c5040c Fixed the Rails 6.1 deprecation
warnings for inherited scoping by making scopes explicit using
`Model.unscoped`, or `Model.default_scoped`. However the
`default_scoped` method added to `Model.nested_set_scope` broke calling
`roots` on `Relatable` when the nested set is scoped:

    bob = User.create!(name: 'Bob')
    bobs_root = bob.categories.create(name: 'Root Category')
    alice = User.create!(name: 'Alice')

    # Alice has no categories so root should return nil
    # Instead it returned bobs_root
    assert_equal(nil, alice.categories.root)

Instead of using two separate classmethods
`nested_set_scope_without_default_scope` and `nested_set_scope` that
apply the scope, we move the `default_scoped` and `unscoped` calls to
`self.class.base_class`. This fixes the `roots` scope and removes the
deprecation warnings.

Also see the Rails discussion:
rails/rails#41066 (comment)

Fixes: collectiveidea#436
@p8 p8 marked this pull request as ready for review January 10, 2021 10:08
@p8
Copy link
Contributor Author

p8 commented Jan 10, 2021

@parndt I've made some changes as suggested by the @kamipo, the author of the deprecation warning:
rails/rails#41066 (comment)

@@ -96,7 +96,7 @@ def case_condition_for_parent

def lock_nodes_between!(left_bound, right_bound)
# select the rows in the model between a and d, and apply a lock
instance_base_class.nested_set_scope.
instance_base_class.default_scoped.nested_set_scope.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Substituting default_scoped with unscoped makes the specs pass as well.
Looking at the previous implementation it seems unscoped could be used, but the scope was probably inherited, hence the warnings...
6c5040c#diff-b1bc4bf228f372cd9fa501fa4d3ade576476fba30f75fbc2ec6de15fb9004444L99

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a tricky one. My typical case where things can get tricky is a default scope that filters out records like

default_scope -> { where(deleted: false) }

In this case it might seem safer to use unscoped and make sure you are locking all records

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@marcrohloff Good point! I think you are correct. I've created a PR to change this:
#450

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok that PR still needs some work...

Copy link
Collaborator

@parndt parndt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for all your effort here @p8. I think it looks good, and we've followed the advice from the Rails team, and all the tests pass.

@parndt parndt merged commit 247716b into collectiveidea:master Jan 10, 2021
parndt added a commit that referenced this pull request Jan 10, 2021
@p8 p8 deleted the fix-root-scope branch January 11, 2021 06:52
@p8
Copy link
Contributor Author

p8 commented Jan 11, 2021

Thanks @parndt !

@p8
Copy link
Contributor Author

p8 commented Jan 15, 2021

@marcrohloff as the author of the original change, I thought you probably wanted to know about these changes.

@clwy-ito
Copy link

@parndt Has the problem been solved?
Please push to rubygems.org

image

@parndt
Copy link
Collaborator

parndt commented Jan 18, 2021

@clwy-cn to clarify, are you asking about the Rails 4.0 regression mentioned in #443, or are you asking about this work on the master branch being pushed as 4.0.0 ?

@clwy-ito
Copy link

clwy-ito commented Jan 19, 2021

@parndt thanks for reply, I am asking about this work.
This is because the version 3.31 , scoped is not working properly,I am using this gem by

gem 'awesome_nested_set', git: 'https://github.com/collectiveidea/awesome_nested_set'

right now.

@parndt
Copy link
Collaborator

parndt commented Jan 19, 2021

@clwy-cn what is your Rails version?

@clwy-cn
Copy link

clwy-cn commented Jan 26, 2021

@parndt

  • rails 6.1.1
  • ruby 3.0.0

@parndt
Copy link
Collaborator

parndt commented Jan 26, 2021

ruby 3.0.0

can you find out for me whether it works on Ruby 2.7.2?

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.

Root returns the wrong result for scoped sets
5 participants