Skip to content

Commit

Permalink
Merge pull request #150 from JagdeepSingh/store-embedded-relations-in…
Browse files Browse the repository at this point in the history
…-parent

Add new option to save embedded relations changes in parent
  • Loading branch information
dblock committed Jun 25, 2016
2 parents 6948018 + dc2bf2e commit 47dcfb8
Show file tree
Hide file tree
Showing 10 changed files with 836 additions and 43 deletions.
6 changes: 4 additions & 2 deletions .rubocop_todo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Lint/HandleExceptions:

# Offense count: 12
Metrics/AbcSize:
Max: 51
Max: 60

# Offense count: 4
Metrics/CyclomaticComplexity:
Expand All @@ -32,7 +32,7 @@ Metrics/MethodLength:
# Offense count: 2
# Configuration parameters: CountComments.
Metrics/ModuleLength:
Max: 168
Max: 188

# Offense count: 4
Metrics/PerceivedComplexity:
Expand All @@ -42,6 +42,7 @@ Metrics/PerceivedComplexity:
Style/Documentation:
Exclude:
- 'lib/mongoid/history.rb'
- 'lib/mongoid/history/options.rb'
- 'lib/mongoid/history/trackable.rb'
- 'lib/mongoid/history/tracker.rb'
- 'lib/mongoid/history/version.rb'
Expand All @@ -52,6 +53,7 @@ Style/Documentation:
- 'spec/integration/nested_embedded_polymorphic_documents_spec.rb'
- 'spec/integration/subclasses_spec.rb'
- 'spec/support/mongoid_history.rb'
- 'spec/unit/options_spec.rb'
- 'spec/unit/trackable_spec.rb'
- 'spec/unit/tracker_spec.rb'

Expand Down
6 changes: 5 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,13 @@ rvm:
- 2.1.1
- 2.0.0
- 1.9.3
- rbx-2.2.10
- rbx-2
- jruby-19mode

matrix:
allow_failures:
- rvm: rbx-2

env:
- MONGOID_VERSION=3
- MONGOID_VERSION=4
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

* Your contribution here.

* [#150](https://github.com/aq1018/mongoid-history/pull/150): Added support for keeping embedded objects audit history in parent itself - [@JagdeepSingh](https://github.com/JagdeepSingh).

0.5.0 (2015/09/18)
------------------

Expand Down
59 changes: 59 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,52 @@ Mongoid::History.disable do
end
```

**Include embedded objects attributes in parent audit**

Modify above `Post` and `Comment` classes as below:

```ruby
class Post
include Mongoid::Document
include Mongoid::Timestamps
include Mongoid::History::Trackable

field :title
field :body
field :rating
embeds_many :comments

track_history :on => [:title, :body, :comments],
:modifier_field => :modifier,
:modifier_field_inverse_of => :nil,
:version_field => :version,
:track_create => true, # track create on Post
:track_update => true,
:track_destroy => false
end

class Comment
include Mongoid::Document
include Mongoid::Timestamps

field :title
field :body
embedded_in :post, :inverse_of => :comments
end

user = User.create(:name => "Aaron")
post = Post.create(:title => "Test", :body => "Post", :modifier => user)
comment = post.comments.build(:title => "test", :body => "comment", :modifier => user)
post.save
post.history_tracks.count # should be 1

comment.respond_to?(:history_tracks) # should be false

track = post.history_tracks.first
track.original # {}
track.modified # { "title" => "Test", "body" => "Post", "comments" => [{ "_id" => "575fa9e667d827e5ed00000d", "title" => "test", "body" => "comment" }], ... }
```

**Retrieving the list of tracked fields**

```ruby
Expand All @@ -172,6 +218,19 @@ Book.tracked_field?(:title) #=> true
Book.tracked_field?(:author) #=> false
```

**Retrieving the list of tracked relations**

```ruby
class Book
...
track_history :on => [:pages]
end

Book.tracked_relation?(:pages) #=> true
Book.tracked_embedded_many #=> ["pages"]
Book.tracked_embedded_many?(:pages) #=> true
```

**Displaying history trackers as an audit trail**

In your Controller:
Expand Down
1 change: 1 addition & 0 deletions lib/mongoid/history.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
require 'easy_diff'
require 'mongoid/compatibility'
require 'mongoid/history/options'
require 'mongoid/history/version'
require 'mongoid/history/tracker'
require 'mongoid/history/trackable'
Expand Down
73 changes: 73 additions & 0 deletions lib/mongoid/history/options.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
module Mongoid
module History
class Options
attr_reader :trackable, :options

def initialize(trackable)
@trackable = trackable
end

def scope
trackable.collection_name.to_s.singularize.to_sym
end

def default_options
{ on: :all,
except: [:created_at, :updated_at],
modifier_field: :modifier,
version_field: :version,
changes_method: :changes,
scope: scope,
track_create: false,
track_update: true,
track_destroy: false }
end

def parse(options = {})
@options = default_options.merge(options)
prepare_skipped_fields
prepare_tracked_fields_and_relations
remove_reserved_fields
@options
end

private

def prepare_skipped_fields
# normalize :except fields to an array of database field strings
@options[:except] = Array(options[:except])
@options[:except] = options[:except].map { |field| trackable.database_field_name(field) }.compact.uniq
end

def prepare_tracked_fields_and_relations
@options[:on] = Array(options[:on])

# :all is just an alias to :fields for now, to support existing users of `mongoid-history`
# In future, :all will track all the fields and associations of trackable class
@options[:on] = options[:on].map { |opt| (opt == :all) ? :fields : opt }
@options[:on] = options[:on].map { |opt| trackable.database_field_name(opt) }.compact.uniq

if options[:on].include?('fields')
@options[:tracked_fields] = trackable.fields.keys
@options[:tracked_relations] = options[:on].reject { |opt| opt == 'fields' }
else
@options[:tracked_fields] = trackable.fields.keys & options[:on]
@options[:tracked_relations] = options[:on] - options[:tracked_fields]
end

@options[:tracked_fields] = options[:tracked_fields] - options[:except]
@options[:tracked_relations] = options[:tracked_relations] - options[:except]
end

def remove_reserved_fields
@options[:tracked_fields] = options[:tracked_fields] - reserved_fields
@options[:tracked_relations] = options[:tracked_relations] - reserved_fields
@options[:tracked_dynamic] = options[:tracked_relations].dup
end

def reserved_fields
['_id', '_type', options[:version_field].to_s, "#{options[:modifier_field]}_id"]
end
end
end
end
Loading

0 comments on commit 47dcfb8

Please sign in to comment.