Skip to content

Commit

Permalink
Update dirty tracking to support Mongoid 8.0+
Browse files Browse the repository at this point in the history
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]
mongodb/mongoid#5092

[new methods]
mongodb/mongoid#5440
  • Loading branch information
carlosantoniodasilva committed Oct 13, 2023
1 parent 7a8c2dd commit d9eb3a5
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 4 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,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)

* bug fixes
* Respect locale set by controller in failure app. Devise will carry over the current I18n.locale option when triggering authentication, and will wrap the failure app call with it. [#5567](https://github.com/heartcombo/devise/pull/5567)
Expand All @@ -26,7 +27,6 @@
* Allow resource class scopes to override the global configuration for `sign_in_after_reset_password` behaviour. [#5429](https://github.com/heartcombo/devise/pull/5429) [@mattr](https://github.com/mattr)
* Refactor conditional dirty tracking logic to a centralized module to simplify usage throughout the codebase. [#5575](https://github.com/heartcombo/devise/pull/5575)
* Improve support for Devise in apps with Active Record and Mongoid ORMs loaded, so it does not incorrectly uses new Active Record dirty tracking APIs with a Mongoid Devise model. [#5576](https://github.com/heartcombo/devise/pull/5576)
* Reenable Mongoid test suite across all Rails 5+ versions, to ensure we continue supporting it. (Note: testing support with Mongoid up to 7.x, not 8 yet.) [#5568](https://github.com/heartcombo/devise/pull/5568)

* bug fixes
* Failure app will respond with configured `redirect_status` instead of `error_status` if the recall app returns a redirect status (300..399) [#5573](https://github.com/heartcombo/devise/pull/5573)
Expand Down
3 changes: 2 additions & 1 deletion gemfiles/Gemfile-rails-main
Original file line number Diff line number Diff line change
Expand Up @@ -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
34 changes: 32 additions & 2 deletions lib/devise/orm.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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

0 comments on commit d9eb3a5

Please sign in to comment.