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

Add new option to save embedded relations changes in parent #150

Merged
merged 12 commits into from
Jun 25, 2016
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