From dd7ee27f74f919eacc48337c966cdcb648d9e2f0 Mon Sep 17 00:00:00 2001 From: Carlos Antonio da Silva Date: Fri, 31 Oct 2025 11:16:02 -0300 Subject: [PATCH] Bring back Mongoid official support (#5568) Devise hasn't been tested with Mongoid since Rails version 5, only 4.x was still running those tests. This enables the tests again on all currently supported Rails versions, with their respective mongoid supported versions. There were a couple of minor tweaks to make it happen, namely: * The way we were dropping the session before doesn't work in later versions so I changed back to calling `purge!` which appears to work fine. We used to call `Mongoid.purge!` but that changed in #4686. * Some of the configs in the Rails test app were setting Active Record values when outside of the AR ORM tests, updated those to make sure they are not set when running mongoid ORM tests. * The validations added to the shared admin code in tests were only checking for Rails version 5.1, but we need to use the same check for AR 5.1 that is used in code, otherwise it will try to use methods not available in mongoid there. --- .github/workflows/test.yml | 15 +++++------- CHANGELOG.md | 1 + Gemfile | 15 ++++-------- Gemfile.lock | 19 ++++++++++++++-- gemfiles/Gemfile-rails-7-0 | 4 ++++ gemfiles/Gemfile-rails-7-1 | 4 ++++ gemfiles/Gemfile-rails-7-2 | 6 ++++- gemfiles/Gemfile-rails-8-0 | 6 ++++- gemfiles/Gemfile-rails-main | 6 ++++- lib/devise/orm.rb | 34 ++++++++++++++++++++++++++-- test/orm/mongoid.rb | 2 +- test/rails_app/config/application.rb | 6 +++-- 12 files changed, 88 insertions(+), 30 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 961fc470..c3f2e666 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -19,14 +19,10 @@ jobs: - '3.1' - '3.0' - '2.7' - env: - - DEVISE_ORM=active_record - - DEVISE_ORM=mongoid + orm: + - active_record + - mongoid exclude: - - gemfile: Gemfile - env: DEVISE_ORM=mongoid - - gemfile: gemfiles/Gemfile-rails-main - env: DEVISE_ORM=mongoid - gemfile: Gemfile ruby: '3.1' - gemfile: Gemfile @@ -52,12 +48,13 @@ jobs: runs-on: ubuntu-latest env: # $BUNDLE_GEMFILE must be set at the job level, so it is set for all steps BUNDLE_GEMFILE: ${{ matrix.gemfile }} + DEVISE_ORM: ${{ matrix.orm }} steps: - uses: actions/checkout@v3 - uses: ruby/setup-ruby@v1 with: ruby-version: ${{ matrix.ruby }} bundler-cache: true # runs bundle install and caches installed gems automatically - - uses: supercharge/mongodb-github-action@1.9.0 - if: ${{ matrix.env == 'DEVISE_ORM=mongoid' }} + - uses: supercharge/mongodb-github-action@1.11.0 + if: ${{ matrix.orm == 'mongoid' }} - run: bundle exec rake diff --git a/CHANGELOG.md b/CHANGELOG.md index 95f92d3c..5272e319 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,7 @@ ``` so it's possible to override `password_length` at runtime. (@manojmj92) + * Reenable Mongoid test suite across all Rails 7+ versions, to ensure we continue supporting it. Changes to dirty tracking to support Mongoid 8.0+. [#5568](https://github.com/heartcombo/devise/pull/5568) * bug fixes * Make `Devise` work without `ActionMailer` when `Zeitwerk` autoloader is used. diff --git a/Gemfile b/Gemfile index 88da13e2..0f18834e 100644 --- a/Gemfile +++ b/Gemfile @@ -23,16 +23,9 @@ group :test do end platforms :ruby do - gem "sqlite3", "~> 2.1" + gem "sqlite3" end -# platforms :jruby do -# gem "activerecord-jdbc-adapter" -# gem "activerecord-jdbcsqlite3-adapter" -# gem "jruby-openssl" -# end - -# TODO: -# group :mongoid do -# gem "mongoid", "~> 4.0.0" -# end +group :mongoid do + gem "mongoid", "~> 9.0", github: "mongodb/mongoid", branch: "9.0-stable" +end diff --git a/Gemfile.lock b/Gemfile.lock index 00485506..1aec779e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,3 +1,13 @@ +GIT + remote: https://github.com/mongodb/mongoid.git + revision: 1d3deaa9d028176988205f541ee588621030662a + branch: 9.0-stable + specs: + mongoid (9.0.8) + activemodel (>= 5.1, < 8.2, != 7.0.0) + concurrent-ruby (>= 1.0.5, < 2.0) + mongo (>= 2.18.0, < 3.0.0) + PATH remote: . specs: @@ -88,6 +98,7 @@ GEM base64 (0.3.0) bcrypt (3.1.20) bigdecimal (3.3.1) + bson (5.2.0) builder (3.3.0) concurrent-ruby (1.3.5) connection_pool (2.5.4) @@ -131,6 +142,9 @@ GEM minitest (5.26.0) mocha (2.7.1) ruby2_keywords (>= 0.0.5) + mongo (2.21.3) + base64 + bson (>= 4.14.1, < 6.0.0) multi_xml (0.7.2) bigdecimal (~> 3.1) net-http (0.6.0) @@ -276,6 +290,7 @@ PLATFORMS DEPENDENCIES devise! mocha (~> 2.1) + mongoid (~> 9.0)! omniauth omniauth-facebook omniauth-oauth2 @@ -285,9 +300,9 @@ DEPENDENCIES rdoc responders (~> 3.1) rexml - sqlite3 (~> 2.1) + sqlite3 timecop webrat BUNDLED WITH - 2.4.5 + 2.6.9 diff --git a/gemfiles/Gemfile-rails-7-0 b/gemfiles/Gemfile-rails-7-0 index cfd7bbe3..625664d0 100644 --- a/gemfiles/Gemfile-rails-7-0 +++ b/gemfiles/Gemfile-rails-7-0 @@ -23,3 +23,7 @@ end platforms :ruby do gem "sqlite3", "~> 1.4" end + +group :mongoid do + gem "mongoid", "~> 7.5" +end diff --git a/gemfiles/Gemfile-rails-7-1 b/gemfiles/Gemfile-rails-7-1 index f455a30a..1eda668a 100644 --- a/gemfiles/Gemfile-rails-7-1 +++ b/gemfiles/Gemfile-rails-7-1 @@ -23,3 +23,7 @@ end platforms :ruby do gem "sqlite3", "~> 1.4" end + +group :mongoid do + gem "mongoid", "~> 8.1" +end diff --git a/gemfiles/Gemfile-rails-7-2 b/gemfiles/Gemfile-rails-7-2 index 85ff6ba8..ed06ba5e 100644 --- a/gemfiles/Gemfile-rails-7-2 +++ b/gemfiles/Gemfile-rails-7-2 @@ -22,5 +22,9 @@ group :test do end platforms :ruby do - gem "sqlite3", "~> 1.4" + gem "sqlite3" +end + +group :mongoid do + gem "mongoid", "~> 8.1" end diff --git a/gemfiles/Gemfile-rails-8-0 b/gemfiles/Gemfile-rails-8-0 index d5d54536..8753badd 100644 --- a/gemfiles/Gemfile-rails-8-0 +++ b/gemfiles/Gemfile-rails-8-0 @@ -21,5 +21,9 @@ group :test do end platforms :ruby do - gem "sqlite3", "~> 2.1" + gem "sqlite3" +end + +group :mongoid do + gem "mongoid", "~> 8.1" end diff --git a/gemfiles/Gemfile-rails-main b/gemfiles/Gemfile-rails-main index f361fad4..69d384ac 100644 --- a/gemfiles/Gemfile-rails-main +++ b/gemfiles/Gemfile-rails-main @@ -21,5 +21,9 @@ group :test do end platforms :ruby do - gem "sqlite3", "~> 2.0" + gem "sqlite3" +end + +group :mongoid do + gem "mongoid", github: "mongodb/mongoid", branch: "master" end diff --git a/lib/devise/orm.rb b/lib/devise/orm.rb index 3e9852cd..4c3cd6f4 100644 --- a/lib/devise/orm.rb +++ b/lib/devise/orm.rb @@ -5,10 +5,14 @@ module Devise end def self.included(model) - model.include DirtyTrackingMethods + if Devise::Orm.active_record?(model) + model.include DirtyTrackingActiveRecordMethods + else + model.include DirtyTrackingMongoidMethods + end end - module DirtyTrackingMethods + module DirtyTrackingActiveRecordMethods def devise_email_before_last_save email_before_last_save end @@ -33,5 +37,31 @@ module Devise respond_to?("will_save_change_to_#{attribute}?") && send("will_save_change_to_#{attribute}?") end end + + module DirtyTrackingMongoidMethods + def devise_email_before_last_save + respond_to?(:email_previously_was) ? email_previously_was : email_was + end + + def devise_email_in_database + email_was + end + + def devise_saved_change_to_email? + respond_to?(:email_previously_changed?) ? email_previously_changed? : email_changed? + end + + def devise_saved_change_to_encrypted_password? + respond_to?(:encrypted_password_previously_changed?) ? encrypted_password_previously_changed? : encrypted_password_changed? + end + + def devise_will_save_change_to_email? + email_changed? + end + + def devise_respond_to_and_will_save_change_to_attribute?(attribute) + respond_to?("#{attribute}_changed?") && send("#{attribute}_changed?") + end + end end end diff --git a/test/orm/mongoid.rb b/test/orm/mongoid.rb index d31bc4d2..5b8807f1 100644 --- a/test/orm/mongoid.rb +++ b/test/orm/mongoid.rb @@ -10,6 +10,6 @@ end class ActiveSupport::TestCase setup do - Mongoid.default_session.drop + Mongoid::Config.purge! end end diff --git a/test/rails_app/config/application.rb b/test/rails_app/config/application.rb index 2371eb08..fc3b171d 100644 --- a/test/rails_app/config/application.rb +++ b/test/rails_app/config/application.rb @@ -40,8 +40,10 @@ module RailsApp Devise::SessionsController.layout "application" end - if Devise::Test.rails70? - config.active_record.legacy_connection_handling = false + if DEVISE_ORM == :active_record + if Devise::Test.rails70? + config.active_record.legacy_connection_handling = false + end end if Devise::Test.rails70_and_up?