diff --git a/CHANGELOG.md b/CHANGELOG.md index cf8b08a9..7519cd4f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ ### 0.6.2 (Next) * Your contribution here. +* [#191](https://github.com/mongoid/mongoid-history/pull/191): Track changes on embed_one - [@mateuspontes](https://github.com/mateuspontes). ### 0.6.1 (2017/01/04) diff --git a/lib/mongoid/history/attributes/update.rb b/lib/mongoid/history/attributes/update.rb index b1499285..c40ea638 100644 --- a/lib/mongoid/history/attributes/update.rb +++ b/lib/mongoid/history/attributes/update.rb @@ -13,6 +13,7 @@ def attributes @attributes[k] = format_field(k, v) end end + insert_embeds_one_changes_on_child if trackable_class.tracked_embeds_one.present? && changes.empty? @attributes end @@ -27,6 +28,22 @@ def insert_embeds_one_changes(relation, value) @attributes[relation][1] = value[1][paranoia_field].present? ? {} : format_embeds_one_relation(relation, value[1]) end + def insert_embeds_one_changes_on_child + trackable_class.tracked_embeds_one.each do |rel| + rel_class = trackable_class.embeds_one_class(rel) + paranoia_field = Mongoid::History.trackable_class_settings(rel_class)[:paranoia_field] + paranoia_field = rel_class.aliased_fields.key(paranoia_field) || paranoia_field + rel = aliased_fields.key(rel) || rel + obj = trackable.send(rel) + next if !obj || (obj.respond_to?(paranoia_field) && obj.public_send(paranoia_field).present?) + @attributes[rel] = {} + obj.changes.each do |k, v| + @attributes[rel] = [{ k => v.first }, { k => v.last }] + end + end + @attributes + end + def insert_embeds_many_changes(relation, value) relation = trackable_class.database_field_name(relation) relation_class = trackable_class.embeds_many_class(relation) diff --git a/spec/integration/nested_embedded_documents_tracked_in_parent_spec.rb b/spec/integration/nested_embedded_documents_tracked_in_parent_spec.rb new file mode 100644 index 00000000..fc63d6d7 --- /dev/null +++ b/spec/integration/nested_embedded_documents_tracked_in_parent_spec.rb @@ -0,0 +1,55 @@ +require 'spec_helper' + +describe Mongoid::History::Tracker do + before :all do + # Child model (will be embedded in Parent) + class Child + include Mongoid::Document + include Mongoid::History::Trackable + + field :name + embedded_in :parent, inverse_of: :child + end + + # Parent model (embeds one Child) + class Parent + include Mongoid::Document + include Mongoid::History::Trackable + + field :name, type: String + embeds_one :child + + track_history on: %i[fields embedded_relations], + version_field: :version, + track_create: true, + track_update: true, + track_destroy: false + end + end + + it 'should be able to track history for nested embedded documents in parent' do + p = Parent.new(name: 'bowser') + p.child = Child.new(name: 'todd') + p.save! + + expect(p.history_tracks.length).to eq(1) + change = p.history_tracks.last + expect(change.modified['name']).to eq('bowser') + expect(change.modified['child']['name']).to eq('todd') + + p.update_attributes(name: 'brow') + expect(p.history_tracks.length).to eq(2) + + p.child.name = 'mario' + p.save! + + expect(p.history_tracks.length).to eq(3) + expect(p.history_tracks.last.original['child']['name']).to eq('todd') + expect(p.history_tracks.last.modified['child']['name']).to eq('mario') + end + + after :all do + Object.send(:remove_const, :Parent) + Object.send(:remove_const, :Child) + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 11e4486a..91d645f5 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -22,4 +22,6 @@ Mongo::Logger.logger.level = Logger::INFO if Mongoid::Compatibility::Version.mongoid5? || Mongoid::Compatibility::Version.mongoid6? Mongoid.belongs_to_required_by_default = false if Mongoid::Compatibility::Version.mongoid6? end + config.filter_run focus: true + config.run_all_when_everything_filtered = true end