Skip to content

Revert introduction of forwardable #107

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

Merged
merged 3 commits into from
Jun 22, 2025

Conversation

scpike
Copy link
Contributor

@scpike scpike commented Jun 9, 2025

This PR attempts to fix an incompatibility between mongoid-locker >= 2.0.1 and mongoid-history. The issue was introduced by this PR. See mongoid/mongoid-history#238 (comment) for an example report.

Timeline

Here's a timeline of what I think happened:

  1. Mongoid 7.1.0 introduced a regression (see https://jira.mongodb.org/browse/MONGOID-4849) by switching to the builtin ruby forwardable method of delegation rather than relying on the ActiveSupport-provided delegation used before.
  2. mongoid-locker was made compatible with the regressed version of mongoid in Add forwardable module and upgrade rubocop #86
  3. Mongoid then fixed their regression in 7.1.1+ with mongodb/mongoid@d078acd, which goes back to the active support way of delegating. (I'm not totally sure why mongoid-locker continued to work, but I think it's because requiring forwardable overrides what delegate does, so mongoid-locker gets its expected behavior but other gems have their delegate changed out from under them).

Underlying issue

The forwardable inclusion in mongoid-locker causes incompatibilities when you then include another gem that expects to be able to set up a delegator within a mongoid document class. For example the mongoid-history gem expects to be able to delegate using the active-support style here: https://github.com/mongoid/mongoid-history/blob/c8c4de1235c01252dfbdb9fe6c0abfc078ec1443/lib/mongoid/history/trackable.rb#L24-L25

Fix

This PR reverts the change to introduce forwardable to go back to using the ActiveSupport-provided delegate.

Mongoid 7.1.0 introduced a regression (see
https://jira.mongodb.org/browse/MONGOID-4849) by switching to the
builtin ruby forwardable method of delegation rather than relying on the
ActiveSupport-provided delegation used before.

mongoid-locker was made compatible with the regressed version of mongoid
in mongodb/mongoid#4739

Mongoid then fixed this regression in 7.1.1+ with
mongodb/mongoid@d078acd,
which goes back to the active support way of delegating.

The `forwardable` inclusion in mongoid-locker causes incompatibilities
when you then include another gem that expects to be able to set up a
delegator within a mongoid document class. For example the
`mongoid-history` gem expects to be able to delegate using the
active-support style here:
https://github.com/mongoid/mongoid-history/blob/c8c4de1235c01252dfbdb9fe6c0abfc078ec1443/lib/mongoid/history/trackable.rb#L24-L25

This PR reverts the change to introduce `forwardable`.

See
mongoid/mongoid-history#238 (comment)
for an example of how this interacts poorly with mongoid-history.
@dblock
Copy link
Collaborator

dblock commented Jun 10, 2025

Thanks. Let's add a test that shows the problem?

@scpike
Copy link
Contributor Author

scpike commented Jun 11, 2025

Thanks. Let's add a test that shows the problem?

I couldn't think of a reasonable way to do this - can you point me in the direction you'd prefer? It seems strange and outside the scope of this gem to have a test that delegate :x, to: :y still passes after this gem is required.

I could add a test dependency on mongoid-history and try to set up a mongoid document that fails if forwardable is require'd. That's maybe a better integration test but also kind of strange.

@dblock
Copy link
Collaborator

dblock commented Jun 12, 2025

Maybe just add a simple integration test ala https://github.com/ruby-grape/grape/tree/master/spec/integration?

@@ -2,6 +2,9 @@

ENV['RACK_ENV'] = 'test'

require 'bundler'
Bundler.require :default, :test
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is required for defined?(Mongoid::History) to be true in the integration spec.

@scpike
Copy link
Contributor Author

scpike commented Jun 12, 2025

Maybe just add a simple integration test ala https://github.com/ruby-grape/grape/tree/master/spec/integration?

Ok I took a stab at it. If you cherry-pick 9cb3e2d over to master the new spec will fail.

Copy link
Collaborator

@dblock dblock left a comment

Choose a reason for hiding this comment

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

Looking good! Fix CI, I have some nits and we're good to go, thanks for fixing this.

# This replicates the exception reported at https://github.com/mongoid/mongoid-history/issues/238#issuecomment-1063155193
# when mongoid-locker required 'forwardable' instead of relying on the
# active support-provided delegation method
RSpec.describe 'MongoidHistory', if: defined?(Mongoid::History) do # rubocop:disable RSpec/DescribeClass
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is the if: needed? I expected for the test to be predictable.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I was setting this up to be similar to what you linked to over at https://github.com/ruby-grape/grape/tree/master/spec/integration, where you have a suite of integration tests where not all gems are required all the time, but rather required conditionally for the various combination tests.

It would still work to remove this check or even remove appraisal entirely.

@dblock
Copy link
Collaborator

dblock commented Jun 21, 2025

Sorry for the delay, CI has an issue.

I have to approve it here in the upstream for first time contributors, but you can definitely see it in your fork when you push, so iterate to 🍏 . Thanks!

@scpike scpike force-pushed the revert-forwardable-inclusion branch from 9f4e509 to a1e5086 Compare June 22, 2025 01:47
@scpike scpike force-pushed the revert-forwardable-inclusion branch from e0b95ae to 794f081 Compare June 22, 2025 02:03
@dblock
Copy link
Collaborator

dblock commented Jun 22, 2025

Merging, thanks, will deal with the jruby failure in #108

@dblock dblock merged commit 138f1a2 into mongoid:master Jun 22, 2025
16 of 19 checks passed
@dblock
Copy link
Collaborator

dblock commented Jun 22, 2025

If you want to do some more work here, the test matrix could use an upgrade to include more recent versions of rubies/MongoDBs.

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.

2 participants