Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: track changes on embedded_one #191

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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)

Expand Down
17 changes: 17 additions & 0 deletions lib/mongoid/history/attributes/update.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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?
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems strange that you'd have the changes.empty? check here. Maybe write a spec that changes fields, then embeds, then both. Then we're keeping things in @attributes, so I imagine this really should be something like

@attributes ||= begin
   changes_in_this_instance_or_something_like_that  + changes_in_embeds + ...
end

@attributes
end

Expand All @@ -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
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be renamed and refactored to return changes on embeds. The code for non-embeds should be changed to return changes on non-embeds, finally attributes should collect all of the things.

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)
Expand Down
Original file line number Diff line number Diff line change
@@ -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
2 changes: 2 additions & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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