relational-audit 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: dad27440866b5d2d553eda59861d13d830928b11
4
+ data.tar.gz: 4e1df4796c9ab299185310ed47b5d13dc3d31ff1
5
+ SHA512:
6
+ metadata.gz: 706c89afb06ab0eb881b153a74701f735e54298c81a4580c84121d6ae2c9a6a186850952418570de62d48b5d6f97ea18b81b138d534910c394dcd44ef7ee46f6
7
+ data.tar.gz: db7c4ea3ebc1aa6dfb24721c1ef7df8699ef04a3eb713aff4b5c6153a041e3de0a65d5a581dc93c357aa0f4f2949a1d12709aa728be94183b5c1af641ceefccc
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in relational-audit.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Manojs
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 TODO: Write your name
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,32 @@
1
+ # Relational::Audit
2
+
3
+ Audit for entities not for table.
4
+ Entity consists of information from multiple related tables.
5
+
6
+ ## Installation
7
+
8
+ Add this line to your application's Gemfile:
9
+
10
+ ```ruby
11
+ gem 'relational-audit'
12
+ ```
13
+
14
+ And then execute:
15
+
16
+ $ bundle
17
+
18
+ Or install it yourself as:
19
+
20
+ $ gem install relational-audit
21
+
22
+ ## Usage
23
+
24
+ TODO: Write usage instructions here
25
+
26
+ ## Contributing
27
+
28
+ 1. Fork it ( https://github.com/[my-github-username]/relational-audit/fork )
29
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
30
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
31
+ 4. Push to the branch (`git push origin my-new-feature`)
32
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,16 @@
1
+ require 'rails/generators'
2
+ require 'rails/generators/active_record'
3
+ module RelationalAudit
4
+ class InstallGenerator < ::Rails::Generators::Base
5
+ include ::Rails::Generators::Migration
6
+ source_root File.expand_path('../templates', __FILE__)
7
+ class_option :with_changes, :type => :boolean, :default => false, :desc => "Store changeset (diff) with each version"
8
+ desc 'Generates (but does not run) a migration to add a relational_audits & audit_relations table.'
9
+ def create_migration_file
10
+ migration_template 'create_relational_audits.rb', 'db/migrate/create_relational_audits.rb'
11
+ end
12
+ def self.next_migration_number(dirname)
13
+ ::ActiveRecord::Generators::Base.next_migration_number(dirname)
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,23 @@
1
+ class CreateRelationalAudits < ActiveRecord::Migration
2
+ def change
3
+ create_table :audits do |t|
4
+ t.string :entity_type, :null => false
5
+ t.integer :entity_id, :null => false
6
+ t.string :event, :null => false
7
+ t.string :changes_by
8
+ t.text :entity_changes
9
+ t.string :transaction_id
10
+ t.datetime :created_at
11
+ end
12
+
13
+ create_table :audit_relations do |t|
14
+ t.integer :audit_id
15
+ t.string :relation_type
16
+ t.integer :relation_id
17
+ t.datetime :created_at
18
+ end
19
+
20
+ add_index :audits, [:entity_type, :entity_id]
21
+ add_index :audit_relations, [:audit_id, :relation_id]
22
+ end
23
+ end
@@ -0,0 +1,196 @@
1
+ require "relational/audit/version"
2
+ require 'securerandom'
3
+ require 'relational/controller_methods.rb'
4
+
5
+ module Relational
6
+ module Audit
7
+
8
+ @@audit_changes_by = nil
9
+
10
+ def self.audit_changes_by=(user)
11
+ @@audit_changes_by = user
12
+ end
13
+
14
+ def self.audit_changes_by
15
+ @@audit_changes_by
16
+ end
17
+
18
+ @@audit_transaction_id = nil
19
+
20
+ def self.audit_transaction_id=(user)
21
+ @@audit_transaction_id = user
22
+ end
23
+
24
+ def self.audit_transaction_id
25
+ @@audit_transaction_id
26
+ end
27
+
28
+ module Event
29
+ CREATE = 'C'
30
+ UPDATE = 'U'
31
+ DESTROY = 'D'
32
+ end
33
+
34
+ module InstanceMethod
35
+
36
+ def raw_audits
37
+ ::RelationalAudit::Audit.joins('join audit_relations on audits.id = audit_relations.audit_id').where("audit_relations.relation_type = ? and audit_relations.relation_id = ?", self.class.name, self.id)
38
+ end
39
+
40
+ def audits(order='DESC')
41
+ grouped_audits = {}
42
+ self.raw_audits.order("id #{order}").each do |audit|
43
+ grouped_audits[audit.transaction_id] ||= []
44
+ grouped_audits[audit.transaction_id] << audit
45
+ end
46
+
47
+ entity_audits = grouped_audits.collect do |transaction_id, audits|
48
+ unless audits.blank?
49
+ merged_audit = {:changes_by => audits.first.changes_by, :changes => {}}
50
+ audits.each do |audit|
51
+ merged_audit[:changes].merge!(audit.changeset)
52
+ end
53
+ merged_audit
54
+ end
55
+ end.compact
56
+
57
+ entity_audits
58
+ end
59
+
60
+ def add_created_relational_audit
61
+ add_audit(::Relational::Audit::Event::CREATE, [self])
62
+ end
63
+
64
+ def add_updated_relational_audit
65
+ add_audit(::Relational::Audit::Event::UPDATE, [self])
66
+ end
67
+
68
+ def add_destroyed_relational_audit
69
+ add_audit(::Relational::Audit::Event::DESTROY, [self])
70
+ end
71
+
72
+ def add_audit event_type, related_to
73
+
74
+ hash_changes = self.changes
75
+
76
+ options = self.class.audit_options
77
+
78
+ unless options[:only].blank?
79
+ hash_changes.delete_if { |key, value| !options[:only].include?(key.intern) }
80
+ end
81
+
82
+ unless options[:ignore].blank?
83
+ hash_changes.delete_if { |key, value| options[:ignore].include?(key.intern) }
84
+ end
85
+
86
+ return if hash_changes.blank?
87
+
88
+ serialized_changes = YAML::dump hash_changes
89
+
90
+ audit = ::RelationalAudit::Audit.new(
91
+ :entity_type => self.class.name,
92
+ :entity_id => self.id,
93
+ :entity_changes => serialized_changes,
94
+ :changes_by => ::Relational::Audit.audit_changes_by,
95
+ :event => event_type,
96
+ :transaction_id => ::Relational::Audit::audit_transaction_id
97
+ )
98
+
99
+ related_to.each do |entity|
100
+ audit.audit_relations.build(
101
+ :relation_type => entity.class.name,
102
+ :relation_id => entity.id
103
+ )
104
+ end
105
+
106
+ audit.save
107
+ end
108
+
109
+ def add_child_audit(event_type)
110
+ related_to = self.class.audit_entities.collect do |entity|
111
+ self.send(entity)
112
+ end
113
+ related_to.push(self)
114
+
115
+ add_audit(event_type, related_to.compact)
116
+ end
117
+
118
+ def add_created_child_audit
119
+ self.add_child_audit(::Relational::Audit::Event::CREATE)
120
+ end
121
+
122
+ def add_updated_child_audit
123
+ self.add_child_audit(::Relational::Audit::Event::UPDATE)
124
+ end
125
+
126
+ def add_destroyed_child_audit
127
+ self.add_child_audit(::Relational::Audit::Event::DESTROY)
128
+ end
129
+
130
+ end
131
+
132
+ module ClassMethod
133
+
134
+ def audit_entities
135
+ self.class_variable_get :@@audit_entities
136
+ end
137
+
138
+ def audit_entities=(audit_entities)
139
+ self.class_variable_set :@@audit_entities, (audit_entities.is_a?(Array) ? audit_entities : [audit_entities])
140
+ end
141
+
142
+ def audit_options
143
+ self.class_variable_get :@@audit_options
144
+ end
145
+
146
+ def audit_options=(audit_options)
147
+ self.class_variable_set :@@audit_options, audit_options
148
+ end
149
+
150
+ def relational_audit audit_options={}
151
+ self.audit_options = audit_options unless audit_options.blank?
152
+
153
+ after_create :add_created_relational_audit
154
+ after_update :add_updated_relational_audit
155
+ after_destroy :add_destroyed_relational_audit
156
+ end
157
+
158
+ def belongs_to_audit audit_entities, audit_options={}
159
+ self.audit_entities = audit_entities
160
+ self.audit_options = audit_options unless audit_options.blank?
161
+
162
+ after_create :add_created_child_audit
163
+ after_update :add_updated_child_audit
164
+ after_destroy :add_destroyed_child_audit
165
+ end
166
+
167
+ end
168
+
169
+ end
170
+ end
171
+
172
+ # ================================================
173
+
174
+ ActiveRecord::Base.send :extend, Relational::Audit::ClassMethod
175
+ ActiveRecord::Base.send :include, Relational::Audit::InstanceMethod
176
+
177
+ if defined?(::ActionController)
178
+ ::ActiveSupport.on_load(:action_controller) { include Relational::Audit::ControllerMethods::InstanceMethods }
179
+ end
180
+
181
+
182
+ module RelationalAudit
183
+ class Audit < ActiveRecord::Base
184
+ has_many :audit_relations
185
+
186
+ def changeset
187
+ YAML::load(self.entity_changes)
188
+ end
189
+ end
190
+
191
+ class AuditRelation < ActiveRecord::Base
192
+ belongs_to :audit
193
+ end
194
+ end
195
+
196
+ # ================================================
@@ -0,0 +1,5 @@
1
+ module Relational
2
+ module Audit
3
+ VERSION = "1.0.3"
4
+ end
5
+ end
@@ -0,0 +1,20 @@
1
+ module Relational
2
+ module Audit
3
+ module ControllerMethods
4
+
5
+ module InstanceMethods
6
+
7
+ def self.included(base)
8
+ base.before_filter :audit_set_changes_by
9
+ end
10
+
11
+ def audit_set_changes_by
12
+ ::Relational::Audit.audit_changes_by = current_user if defined? current_user
13
+ ::Relational::Audit.audit_transaction_id = SecureRandom.hex(10)
14
+ end
15
+
16
+ end
17
+
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'relational/audit/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "relational-audit"
8
+ spec.version = Relational::Audit::VERSION
9
+ spec.authors = ["Manojs"]
10
+ spec.email = ["manojs.nitt@gmail.com"]
11
+ spec.summary = %q{Audit for entities not for table. Entity consists of information from multiple related tables}
12
+ spec.description = %q{Audit for entities not for table. Entity consists of information from multiple related tables}
13
+ spec.homepage = "https://github.com/bethink/relational-audit"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.7"
22
+ spec.add_development_dependency "rake", "~> 10.0"
23
+
24
+ spec.add_dependency 'activerecord', ['>= 3.0', '< 5.0']
25
+ spec.add_dependency 'activesupport', ['>= 3.0', '< 5.0']
26
+ end
metadata ADDED
@@ -0,0 +1,126 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: relational-audit
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.3
5
+ platform: ruby
6
+ authors:
7
+ - Manojs
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-01-02 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: activerecord
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ - - <
49
+ - !ruby/object:Gem::Version
50
+ version: '5.0'
51
+ type: :runtime
52
+ prerelease: false
53
+ version_requirements: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - '>='
56
+ - !ruby/object:Gem::Version
57
+ version: '3.0'
58
+ - - <
59
+ - !ruby/object:Gem::Version
60
+ version: '5.0'
61
+ - !ruby/object:Gem::Dependency
62
+ name: activesupport
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - '>='
66
+ - !ruby/object:Gem::Version
67
+ version: '3.0'
68
+ - - <
69
+ - !ruby/object:Gem::Version
70
+ version: '5.0'
71
+ type: :runtime
72
+ prerelease: false
73
+ version_requirements: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '3.0'
78
+ - - <
79
+ - !ruby/object:Gem::Version
80
+ version: '5.0'
81
+ description: Audit for entities not for table. Entity consists of information from
82
+ multiple related tables
83
+ email:
84
+ - manojs.nitt@gmail.com
85
+ executables: []
86
+ extensions: []
87
+ extra_rdoc_files: []
88
+ files:
89
+ - .gitignore
90
+ - Gemfile
91
+ - LICENSE
92
+ - LICENSE.txt
93
+ - README.md
94
+ - Rakefile
95
+ - lib/generators/relational_audit/install_generator.rb
96
+ - lib/generators/relational_audit/templates/create_relational_audits.rb
97
+ - lib/relational/audit.rb
98
+ - lib/relational/audit/version.rb
99
+ - lib/relational/controller_methods.rb
100
+ - relational-audit.gemspec
101
+ homepage: https://github.com/bethink/relational-audit
102
+ licenses:
103
+ - MIT
104
+ metadata: {}
105
+ post_install_message:
106
+ rdoc_options: []
107
+ require_paths:
108
+ - lib
109
+ required_ruby_version: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - '>='
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ required_rubygems_version: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - '>='
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ requirements: []
120
+ rubyforge_project:
121
+ rubygems_version: 2.4.5
122
+ signing_key:
123
+ specification_version: 4
124
+ summary: Audit for entities not for table. Entity consists of information from multiple
125
+ related tables
126
+ test_files: []