Dirty tracking refactor #211
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Complete refactor of dirty tracking of CouchRest Model properties. The objective is to fix the issues with nested objects and failing to detect changes in complex models that don't use the
Embeddable
class. ActiveModel Dirty wasn't designed for this level of complexity, so was falling short.This dirty tracking proposal uses the Hashdiff gem to compare a cached "raw" hash of attributes, including nested objects. The smallest change is picked out, regardless of the complexity of the underlying data.
The only caveat with the Hashdiff gem is that the comparison results uses a special format that is not comparable to the standard result from ActiveModel. Given that CouchDB is not capable of partial updates, this seems an acceptable tradeoff for reliability. Some methods provided by
ActiveModel::Dirty
are also no longer available:changes_applied
,restore_attributes
,previous_changes
, andchanged_attributes
.Also of note is that comparisons are always performed using "raw" data; the documents that will actually be sent for storage. This makes comparisons simpler and more reliable, but may cause confusion when trying to use the results of a comparison.
If you're worried about the performance of the Hashdiff gem and extra memory requirements, dirty tracking can be disabled either globally, or on a model-level using the
disable_dirty_tracking
configuration option.