rails_log_book 0.3.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 1dcd95f53c62fb9971f9b6aa3600f083fe20e390
4
- data.tar.gz: 5c8d602213701f68f25b4ea419bba3b415e25f4b
2
+ SHA256:
3
+ metadata.gz: 33c84201892d61f332f7f60bd66ac9d052c37b9d9a894e5210eecf528efcb1ee
4
+ data.tar.gz: 2dd8618869a1a1955e8c24261edbd11561662792d39e736de94513ea32b28358
5
5
  SHA512:
6
- metadata.gz: cf696b59c7b89efea1dbb24525750653d1507e3b78803a4ae2c36076348f73d9099210ba75ad54c2f5f8f79d90cf7d2792f4d12becff5f5ba6867198991aebf5
7
- data.tar.gz: 70d8ddd9694e9221d4347e1aaaaa5ceb8859cab8a0d224bca164bb1e989e4643956710ac216b2717fc05ff749fd37ed6f8708f7e6622f723aea8bd53da127634
6
+ metadata.gz: 1f0b026c941e50454283953976c11eef81cba06e8c37ddb6ffaffbfb1ca1c3ef030c1b6e82c5be68c9151948465fa335ae4f3b79a8e2606a4a0190559e6f07cd
7
+ data.tar.gz: 0b321da7a85b6fe8620fe1863ac26560c3dd40a5fa06eabf1a7d4d1ec0f299d296994634370bac9c66a82990440ae2d578ced623b617474d2f864ec8b6443bde
data/README.md CHANGED
@@ -1,29 +1,185 @@
1
1
  # LogBook
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/log_book`. To experiment with that code, run `bin/console` for an interactive prompt.
3
+ LogBook is a gem that tracks changes on your records. Created for the purpuse of auditing and showing activity log.
4
+ For comparison with [paper_\__trail](https://github.com/airblade/paper_trail) and [audited](https://github.com/collectiveidea/audited) see []()
4
5
 
5
- TODO: Delete this and the text above, and describe your gem
6
+ ## Supported ORMs
6
7
 
7
- ## Installation
8
+ Currently only supports ActiveRecord.
8
9
 
9
- Add this line to your application's Gemfile:
10
+ ## Instalation
11
+
12
+ Add to your Gemfile:
13
+
14
+ ``` ruby
15
+ gem 'rails_log_book'
16
+ ```
17
+
18
+ Then run:
10
19
 
11
20
  ```ruby
12
- gem 'log_book'
21
+ rails generate log_book:install
22
+ rake db:migrate
13
23
  ```
14
24
 
15
- And then execute:
25
+ ## Usage
16
26
 
17
- $ bundle
27
+ Add to models you want to keep track of:
18
28
 
19
- Or install it yourself as:
29
+ ``` ruby
30
+ class User < ActiveRecord::Base
31
+ include LogBook::Recorder
20
32
 
21
- $ gem install log_book
33
+ has_log_book_records
34
+ end
35
+ ```
22
36
 
23
- ## Usage
37
+ Add to controlers and actions you want the tracker to be active:
38
+
39
+ ``` ruby
40
+ class UsersController < ApplicationController
41
+ include LogBook::ControllerRecord
42
+ end
43
+ ```
44
+
45
+ By default, whenever a user record is created, updated or deleted in any actions of users\_controller a new log\_book record will be created.
46
+
47
+ ## ActiveRecord Options
48
+
49
+ ### fields
50
+
51
+ ``` ruby
52
+ class User < ActiveRecord::Base
53
+ include LogBook::Recorder
54
+
55
+ # all fields
56
+ # has_log_book_records
24
57
 
25
- TODO: Write usage instructions here
58
+ # Only fields
59
+ # has_log_book_records only: [:email, :name]
60
+
61
+ # Ignored fields
62
+ # has_log_book_records except: [:password]
63
+
64
+ # Default ignored fields
65
+ # primary_key (id), LogBook.config.ignored_attributes (:created_at, :updated_at)
66
+ end
67
+ ```
68
+
69
+ ### callbacks
70
+
71
+ ``` ruby
72
+ class User < ActiveRecord::Base
73
+ include LogBook::Recorder
74
+
75
+ # all events
76
+ # has_log_book_records
77
+
78
+ # Only record on create and destroy (not update)
79
+ # has_log_book_records on: [:create, :destroy]
80
+ end
81
+ ```
82
+
83
+ ### parent
84
+
85
+ Define who is a parent of this object. Will be recorded in a `parent` polymorphic columns
86
+
87
+ ``` ruby
88
+ class User < ActiveRecord::Base
89
+ include LogBook::Recorder
90
+ belongs_to :company
91
+
92
+ # Parent is Company and will be recorded with each user change
93
+ # has_log_book_records parent: :company
94
+ end
95
+ ```
26
96
 
97
+ ### meta
98
+
99
+ Arbitrary column. This is a jsonb field which can have all kinds of information. Useful when you want to cache fields at the exact point of record creation
100
+
101
+ ``` ruby
102
+ class User < ActiveRecord::Base
103
+ include LogBook::Recorder
104
+
105
+ # runs `log_book_meta(record)` method to assign to `:meta` field
106
+ # has_log_book_records meta: true
107
+
108
+ # runs `meta_method` method to assing to `:meta` field
109
+ # has_log_book_records meta: :meta_method
110
+
111
+ # runs passed proc to assing to `:meta` field
112
+ # has_log_book_records meta: -> { { slug: email.split('@').first } }
113
+ end
114
+ ```
115
+
116
+ ### squash
117
+
118
+ Enables/disables suashing on this model
119
+
120
+ ``` ruby
121
+ class User < ActiveRecord::Base
122
+ include LogBook::Recorder
123
+
124
+ # Enables squashing (defaults to false)
125
+ # has_log_book_records squash: true
126
+ ```
127
+
128
+ ## ActionController options
129
+
130
+ ### current\_author
131
+
132
+ Defines what method is run when looking for the author for recording
133
+
134
+ ``` ruby
135
+ class Admin::UsersController < ActionController::Base
136
+ inlcude LogBook::ControllerRecord
137
+
138
+ # defaults to `current_user`
139
+ def current_author
140
+ current_admin
141
+ end
142
+ ```
143
+
144
+ ## Configuration
145
+
146
+ ``` ruby
147
+ # config/initializers/log_book.rb
148
+ LogBook.configure do |config|
149
+ config.records_table_name = 'records'
150
+ config.ignored_attributes = [:updated_at, :created_at]
151
+ config.author_method = :current_user
152
+ config.record_squashing = false
153
+ config.recording_enabled = false
154
+ config.skip_if_empty_actions = [:update]
155
+ end
156
+ ```
157
+
158
+ ## Additional methods
159
+
160
+ ``` ruby
161
+ LogBook.with_recording {} #=> Enables recording within block
162
+ LogBook.without_recording {} #=> Disables recording within block
163
+ LogBook.record_as(author) {} #=> Records as a different author within block
164
+ LogBook.with_record_squashing {} #=> Squashes records within block
165
+ LogBook.enable_recording #=> Enables recording from this point
166
+ LogBook.disable_recording #=> Disables recording from this point
167
+ LogBook.record_squashing_enabled #=> Enables record squashing from this point
168
+ LogBook.recording_enabled #=> Returns true if recording is enabled
169
+ LogBook.recording_enabled=(val) #=> Enables/Disables recording
170
+ LogBook.squash_records #=> Squash records with current :request_uuid
171
+ ```
172
+
173
+ ## Squashing
174
+
175
+ The idea of squashing came when we needed to show an activity page where all changes made in the single request as one change.
176
+
177
+ Each request has its own unique `request_uuid` and it is recorded with each record. If squashing is enabled, `after_action` method with squashing is called.
178
+ All records with the same `request_uuid` are "squashed" into one record.
179
+
180
+ ``` sql
181
+ INSERT INTO "users" ("name", "email") VALUES ("test", "test@test.com")
182
+ ```
27
183
  ## Development
28
184
 
29
185
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -32,7 +188,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
32
188
 
33
189
  ## Contributing
34
190
 
35
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/log_book. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
191
+ Bug reports and pull requests are welcome on GitHub at https://github.com/infinum/log_book. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
36
192
 
37
193
 
38
194
  ## License
@@ -1,6 +1,6 @@
1
1
  require 'rails/generators/migration'
2
2
  require 'generators/log_book/migration'
3
- require 'log_book'
3
+ require 'rails_log_book'
4
4
 
5
5
  module LogBook
6
6
  module Generators
@@ -17,6 +17,12 @@ module LogBook
17
17
  def copy_migration
18
18
  migration_template 'install.rb', 'db/migrate/install_log_book.rb'
19
19
  end
20
+
21
+ def migration_version
22
+ if rails5?
23
+ "[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]"
24
+ end
25
+ end
20
26
  end
21
27
  end
22
28
  end
@@ -1,4 +1,4 @@
1
- class <%= migration_class_name %> < ActiveRecord::Migration
1
+ class <%= migration_class_name %> < ActiveRecord::Migration<%= migration_version %>
2
2
  def change
3
3
  create_table :records do |t|
4
4
  t.belongs_to :author, polymorphic: true, index: true
@@ -6,7 +6,7 @@ class <%= migration_class_name %> < ActiveRecord::Migration
6
6
  t.belongs_to :parent, polymorphic: true, index: true
7
7
  t.jsonb :record_changes, default: {}
8
8
  t.jsonb :meta, default: {}
9
- t.string :request_uuid
9
+ t.string :request_uuid, index: true
10
10
  t.string :action
11
11
 
12
12
  t.datetime :created_at
@@ -21,7 +21,7 @@ module LogBook
21
21
  end
22
22
 
23
23
  def current_author
24
- raise NotImplementedError unless respond_to?(LogBook.config.author_method)
24
+ raise NotImplementedError unless respond_to?(LogBook.config.author_method, true)
25
25
  send(LogBook.config.author_method)
26
26
  end
27
27
  end
@@ -34,19 +34,6 @@ module LogBook
34
34
  self.class.with_recording(&block)
35
35
  end
36
36
 
37
- def new_record
38
- record = LogBook::Record.new(
39
- action: LogBook.store[:action],
40
- record_changes: record_changes,
41
- author: LogBook.store[:author],
42
- subject: self,
43
- meta: {}
44
- )
45
- record.meta = log_book_meta_info(record) if recording_options[:meta].present?
46
- record.parent = send(recording_options[:parent]) if recording_options[:parent].present?
47
- record
48
- end
49
-
50
37
  def recording_attributes
51
38
  attributes.except(*non_recording_columns)
52
39
  end
@@ -60,9 +47,9 @@ module LogBook
60
47
  def record_changes
61
48
  if recording_options[:only]
62
49
  recording_columns = self.class.recording_columns.map(&:name)
63
- changes.slice(*recording_columns)
50
+ saved_changes.slice(*recording_columns)
64
51
  else
65
- changes.except(*non_recording_columns)
52
+ saved_changes.except(*non_recording_columns)
66
53
  end
67
54
  end
68
55
 
@@ -80,12 +67,24 @@ module LogBook
80
67
 
81
68
  def write_record(action)
82
69
  return unless LogBook.recording_enabled
83
- LogBook.store[:action] ||= action
84
- record = new_record
70
+ record = new_record(LogBook.store[:action] || action)
85
71
  return unless record.changes_to_record?
86
72
  record.save
87
73
  end
88
74
 
75
+ def new_record(action)
76
+ record = LogBook::Record.new(
77
+ action: action,
78
+ record_changes: record_changes,
79
+ author: LogBook.store[:author],
80
+ subject: self,
81
+ meta: {}
82
+ )
83
+ record.meta = log_book_meta_info(record) if recording_options[:meta].present?
84
+ record.parent = send(recording_options[:parent]) if recording_options[:parent].present?
85
+ record
86
+ end
87
+
89
88
  def log_book_meta_info(record)
90
89
  case recording_options[:meta]
91
90
  when NilClass then nil
@@ -6,17 +6,28 @@ module LogBook
6
6
 
7
7
  def call
8
8
  records.group_by(&:parent).each do |parent, children|
9
- next if parent.nil?
10
9
  children_to_squash = children.select { |child| child.subject.try(:to_squash?) }
11
10
  next if children_to_squash.empty?
12
11
 
13
- parent_in_records = parent_in_records(parent)
14
- parent_in_records.record_changes.merge!(squashed_changes(children_to_squash, :record_changes))
15
- parent_in_records.meta.merge!(squashed_changes(children_to_squash, :meta))
16
- parent_in_records.created_at ||= children_to_squash.first.created_at
17
- parent_in_records.save
12
+ if parent.present?
13
+ parent_in_records = parent_in_records(parent)
14
+ parent_in_records.record_changes.merge!(squashed_changes(children_to_squash, :record_changes))
15
+ parent_in_records.meta.merge!(squashed_changes(children_to_squash, :meta))
16
+ parent_in_records.created_at ||= children_to_squash.first.created_at
17
+ parent_in_records.save
18
18
 
19
- children_to_squash.each(&:delete)
19
+ children_to_squash.each(&:delete)
20
+ else
21
+ next if children_to_squash.one?
22
+
23
+ records.reduce do |main_record, record|
24
+ main_record.record_changes.merge!(record.record_changes)
25
+ main_record.meta.merge!(record.meta)
26
+
27
+ record.delete
28
+ main_record
29
+ end.save
30
+ end
20
31
  end
21
32
  end
22
33
 
@@ -1,3 +1,3 @@
1
1
  module LogBook
2
- VERSION = "0.3.0"
2
+ VERSION = '1.0.0'
3
3
  end
data/log_book.gemspec CHANGED
@@ -6,7 +6,7 @@ Gem::Specification.new do |spec|
6
6
  spec.name = 'rails_log_book'
7
7
  spec.version = LogBook::VERSION
8
8
  spec.authors = ['Stjepan Hadjic']
9
- spec.email = ['d4be4st@gmail.com']
9
+ spec.email = ['stjepan.hadjic@infinum.co']
10
10
 
11
11
  spec.summary = 'Write a short summary, because Rubygems requires one.'
12
12
  spec.description = 'Write a longer description or delete this line.'
@@ -32,5 +32,5 @@ Gem::Specification.new do |spec|
32
32
  spec.add_development_dependency 'pry-byebug'
33
33
 
34
34
  spec.add_dependency 'request_store'
35
- spec.add_dependency 'activerecord', '>= 4.0', '< 5.1'
35
+ spec.add_dependency 'activerecord', '> 5.2'
36
36
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_log_book
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stjepan Hadjic
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-04-18 00:00:00.000000000 Z
11
+ date: 2018-09-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -112,25 +112,19 @@ dependencies:
112
112
  name: activerecord
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
- - - ">="
116
- - !ruby/object:Gem::Version
117
- version: '4.0'
118
- - - "<"
115
+ - - ">"
119
116
  - !ruby/object:Gem::Version
120
- version: '5.1'
117
+ version: '5.2'
121
118
  type: :runtime
122
119
  prerelease: false
123
120
  version_requirements: !ruby/object:Gem::Requirement
124
121
  requirements:
125
- - - ">="
126
- - !ruby/object:Gem::Version
127
- version: '4.0'
128
- - - "<"
122
+ - - ">"
129
123
  - !ruby/object:Gem::Version
130
- version: '5.1'
124
+ version: '5.2'
131
125
  description: Write a longer description or delete this line.
132
126
  email:
133
- - d4be4st@gmail.com
127
+ - stjepan.hadjic@infinum.co
134
128
  executables: []
135
129
  extensions: []
136
130
  extra_rdoc_files: []
@@ -180,7 +174,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
180
174
  version: '0'
181
175
  requirements: []
182
176
  rubyforge_project:
183
- rubygems_version: 2.5.1
177
+ rubygems_version: 2.7.3
184
178
  signing_key:
185
179
  specification_version: 4
186
180
  summary: Write a short summary, because Rubygems requires one.