From a2f1d29b5975ad5f1bd68c1d7c0e9c22218fb687 Mon Sep 17 00:00:00 2001 From: Carlos Antonio da Silva Date: Fri, 31 Mar 2023 11:41:23 -0300 Subject: [PATCH] Update dirty tracking to support Mongoid 8.0+ It appears Mongoid 8.0+ slightly [changed dirty tracking] behavior to more closely match Active Model/Record, however they haven't yet introduced the [new methods] that match the latest API, that seems to be coming on Mongoid 8.1 only. The changes here try to accommodate for that by determining which "attribute_changed?" method to call depending on whether the "*_previously_*" version exists. Newer versions of AR (5.1+) will continue to use the new API / methods, whereas previous versions and Mongoid 8.0+ will use these tweaked versions. No behavior should change for AR, but it will hopefully support Mongoid 8.0+ now. [changed dirty tracking] https://github.com/mongodb/mongoid/pull/5092 [new methods] https://github.com/mongodb/mongoid/pull/5440 --- CHANGELOG.md | 1 + gemfiles/Gemfile-rails-main | 3 ++- lib/devise/orm.rb | 34 ++++++++++++++++++++++++++++++++-- 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b2c9b55e3..dd4398a73 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ * enhancements * Removed deprecations warning output for `Devise::Models::Authenticatable::BLACKLIST_FOR_SERIALIZATION` (@soartec-lab) + * Reenable Mongoid test suite across all Rails 6+ versions, to ensure we continue supporting it. Changes to dirty tracking to support Mongoid 8.0+. [#5568](https://github.com/heartcombo/devise/pull/5568) Please check [4-stable](https://github.com/heartcombo/devise/blob/4-stable/CHANGELOG.md) for previous changes. diff --git a/gemfiles/Gemfile-rails-main b/gemfiles/Gemfile-rails-main index da31739d1..27e3a394a 100644 --- a/gemfiles/Gemfile-rails-main +++ b/gemfiles/Gemfile-rails-main @@ -25,5 +25,6 @@ platforms :ruby do end group :mongoid do - gem "mongoid", "~> 7.5" + # gem "mongoid", "~> 8.1" + gem "mongoid", github: "mongodb/mongoid", branch: "8.1-stable" end diff --git a/lib/devise/orm.rb b/lib/devise/orm.rb index 3e9852cd3..4c3cd6f49 100644 --- a/lib/devise/orm.rb +++ b/lib/devise/orm.rb @@ -5,10 +5,14 @@ def self.active_record?(model) 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 @@ def devise_respond_to_and_will_save_change_to_attribute?(attribute) 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