operator_recordable 1.2.0 → 1.4.0
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 +4 -4
- data/.rubocop.yml +5 -0
- data/CHANGELOG.md +37 -1
- data/README.md +9 -4
- data/lib/operator_recordable/configuration.rb +9 -3
- data/lib/operator_recordable/recorder.rb +42 -21
- data/lib/operator_recordable/store/thread_store.rb +4 -0
- data/lib/operator_recordable/store.rb +1 -1
- data/lib/operator_recordable/version.rb +1 -1
- data/operator_recordable.gemspec +3 -2
- metadata +23 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 17d5261fe9e0dde7d722753e707a2a5210bc183866be7d9509b6670e2187e432
|
4
|
+
data.tar.gz: 7c569a64a127e3b293ac7d5ed66ba0762774163ef7395d16acd49bd7e30bba85
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6e5d5deec10df7399288037211bf9de8d53ec2b21b4763818e74759de35e84704ee8857945d2afc603fe156aa9bdd541f364e74d871643665dc96adaa8cb8cae
|
7
|
+
data.tar.gz: 6d9ea5667096bd04be4705fc97fe0beccd34aa5d37b1925ede9c7868bd6558a1812db6b798ce1b871505b7461b954fee356bd9cc810a42d2e05ffac3385002ad
|
data/.rubocop.yml
CHANGED
@@ -2,6 +2,7 @@ AllCops:
|
|
2
2
|
Exclude:
|
3
3
|
- gemfiles/**/*
|
4
4
|
TargetRubyVersion: 2.5
|
5
|
+
NewCops: enable
|
5
6
|
|
6
7
|
Style/AsciiComments:
|
7
8
|
Enabled: false
|
@@ -23,6 +24,10 @@ Layout/EndOfLine:
|
|
23
24
|
Layout/LineLength:
|
24
25
|
Max: 128
|
25
26
|
|
27
|
+
Metrics/AbcSize:
|
28
|
+
Exclude:
|
29
|
+
- spec/**/*
|
30
|
+
|
26
31
|
Metrics/BlockLength:
|
27
32
|
Exclude:
|
28
33
|
- spec/**/*
|
data/CHANGELOG.md
CHANGED
@@ -1,12 +1,48 @@
|
|
1
1
|
## Unreleased
|
2
2
|
|
3
3
|
|
4
|
+
## 1.4.0 (2022-08-18)
|
5
|
+
|
6
|
+
### Changes
|
7
|
+
|
8
|
+
* Deprecate `:thread_store`
|
9
|
+
+ [PR#36](https://github.com/yujideveloper/operator_recordable/pull/36)
|
10
|
+
|
11
|
+
### Misc
|
12
|
+
|
13
|
+
* Change the default branch from master to main
|
14
|
+
+ [PR#35](https://github.com/yujideveloper/operator_recordable/pull/35)
|
15
|
+
|
16
|
+
|
17
|
+
## 1.3.1 (2022-06-20)
|
18
|
+
|
19
|
+
### Bug fixes
|
20
|
+
|
21
|
+
* Fix recording discarded_by if the target table uses optimistic lock
|
22
|
+
+ [PR#34](https://github.com/yujideveloper/operator_recordable/pull/34)
|
23
|
+
|
24
|
+
|
25
|
+
## 1.3.0 (2022-06-01)
|
26
|
+
|
27
|
+
### Changes
|
28
|
+
|
29
|
+
* Support discard gem for soft deletes
|
30
|
+
+ [PR#31](https://github.com/yujideveloper/operator_recordable/pull/31)
|
31
|
+
* Get rid of needless guard clauses for ActiveSupport 5.1 and older
|
32
|
+
+ [PR#32](https://github.com/yujideveloper/operator_recordable/pull/32)
|
33
|
+
|
34
|
+
### Misc
|
35
|
+
|
36
|
+
* Fix RuboCop offenses
|
37
|
+
+ [PR#33](https://github.com/yujideveloper/operator_recordable/pull/33)
|
38
|
+
|
39
|
+
|
4
40
|
## 1.2.0 (2022-04-26)
|
5
41
|
|
6
42
|
### Changes
|
7
43
|
|
8
44
|
* Make associations optional
|
9
|
-
+ [PR#28](https://github.com/yujideveloper/operator_recordable/pull/
|
45
|
+
+ [PR#28](https://github.com/yujideveloper/operator_recordable/pull/28)
|
10
46
|
|
11
47
|
### Misc
|
12
48
|
|
data/README.md
CHANGED
@@ -7,6 +7,8 @@
|
|
7
7
|
OperatorRecordable is a Rails plugin gem that makes your ActiveRecord models to be saved or logically deleted with automatically set `created_by`, `updated_by`, and `deleted_by`.
|
8
8
|
Also it makes `creator`, `updater`, and `deleter` `belongs_to` association if a class has `created_by`, `updated_by`, or `deleted_by`.
|
9
9
|
|
10
|
+
It also supports `discarded_by` column if [discard gem](https://github.com/jhawthorn/discard) is available.
|
11
|
+
|
10
12
|
This gem is inspired by [RecordWithOperator](https://github.com/nay/record_with_operator).
|
11
13
|
|
12
14
|
## Installation
|
@@ -38,12 +40,14 @@ OperatorRecordable.config = {
|
|
38
40
|
creator_column_name: "created_by",
|
39
41
|
updater_column_name: "updated_by",
|
40
42
|
deleter_column_name: "deleted_by",
|
43
|
+
discarder_column_name: "discarded_by",
|
41
44
|
creator_association_name: "creator",
|
42
45
|
updater_association_name: "updater",
|
43
46
|
deleter_association_name: "deleter",
|
47
|
+
discarder_association_name: "discarder",
|
44
48
|
operator_association_options: {},
|
45
49
|
operator_association_scope: nil,
|
46
|
-
store: :
|
50
|
+
store: :current_attributes_store
|
47
51
|
}
|
48
52
|
```
|
49
53
|
|
@@ -55,9 +59,11 @@ OperatorRecordable.config = {
|
|
55
59
|
| `creator_column_name` | String | column name of creator. | `"created_by"` |
|
56
60
|
| `updater_column_name` | String | column name of updater. | `"updated_by"` |
|
57
61
|
| `deleter_column_name` | String | column name of deleter. | `"deleted_by"` |
|
62
|
+
| `discarder_column_name` | String | column name of discarder. | `"discarded_by"` |
|
58
63
|
| `creator_association_name` | String | association name of creator. | `"creator"` |
|
59
64
|
| `updater_association_name` | String | association name of updater. | `"updater"` |
|
60
65
|
| `deleter_association_name` | String | association name of deleter. | `"deleter"` |
|
66
|
+
| `discarder_association_name` | String | association name of discarder. | `"discarder"` |
|
61
67
|
| `operator_association_options` | Hash | options of operator associations. e.g. `{ touch: true }` | `{}` |
|
62
68
|
| `operator_association_scope` | Proc | The scope of operator associations. e.g. `-> { with_deleted }` | `nil` |
|
63
69
|
| `store` | Enum | operator store. any value of `:thread_store`, `:request_store` or `:current_attributes_store` | `:thread_store` |
|
@@ -91,7 +97,7 @@ OperatorRecordable.operator = current_operator
|
|
91
97
|
#### `:thread_store`
|
92
98
|
|
93
99
|
This store is implemented by `Thread.current`.
|
94
|
-
This is default store.
|
100
|
+
This is default store. **But this is deprecated and will be removed in v2.0. Please consider using `:current_attributes_store` instead.**
|
95
101
|
|
96
102
|
|
97
103
|
#### `:request_store`
|
@@ -119,8 +125,7 @@ require "operator_recordable/store/request_store"
|
|
119
125
|
|
120
126
|
#### `:current_attributes_store`
|
121
127
|
|
122
|
-
This store is implemented by using [`ActiveSupport::CurrentAttributes`](https://api.rubyonrails.org/v5.2.0/classes/ActiveSupport/CurrentAttributes.html).
|
123
|
-
So, this requires ActiveSupport 5.2 or later.
|
128
|
+
This store is implemented by using [`ActiveSupport::CurrentAttributes`](https://api.rubyonrails.org/v5.2.0/classes/ActiveSupport/CurrentAttributes.html).
|
124
129
|
|
125
130
|
|
126
131
|
## Development
|
@@ -11,8 +11,8 @@ module OperatorRecordable
|
|
11
11
|
@store = initialize_store
|
12
12
|
end
|
13
13
|
|
14
|
-
%i[operator_class_name creator_column_name updater_column_name deleter_column_name
|
15
|
-
creator_association_name updater_association_name deleter_association_name
|
14
|
+
%i[operator_class_name creator_column_name updater_column_name deleter_column_name discarder_column_name
|
15
|
+
creator_association_name updater_association_name deleter_association_name discarder_association_name
|
16
16
|
operator_association_options operator_association_scope].each do |name|
|
17
17
|
define_method name do
|
18
18
|
config[name]
|
@@ -37,9 +37,11 @@ module OperatorRecordable
|
|
37
37
|
creator_column_name: "created_by",
|
38
38
|
updater_column_name: "updated_by",
|
39
39
|
deleter_column_name: "deleted_by",
|
40
|
+
discarder_column_name: "discarded_by",
|
40
41
|
creator_association_name: "creator",
|
41
42
|
updater_association_name: "updater",
|
42
43
|
deleter_association_name: "deleter",
|
44
|
+
discarder_association_name: "discarder",
|
43
45
|
operator_association_options: {},
|
44
46
|
operator_association_scope: nil,
|
45
47
|
store: :thread_store
|
@@ -53,7 +55,7 @@ module OperatorRecordable
|
|
53
55
|
end
|
54
56
|
|
55
57
|
class Model
|
56
|
-
VALID_ACTIONS = %i[create update destroy].freeze
|
58
|
+
VALID_ACTIONS = %i[create update destroy discard].freeze
|
57
59
|
|
58
60
|
def initialize(actions)
|
59
61
|
@actions = actions
|
@@ -72,6 +74,10 @@ module OperatorRecordable
|
|
72
74
|
actions.include? :destroy
|
73
75
|
end
|
74
76
|
|
77
|
+
def record_discarder?
|
78
|
+
actions.include? :discard
|
79
|
+
end
|
80
|
+
|
75
81
|
private
|
76
82
|
|
77
83
|
attr_reader :actions
|
@@ -31,6 +31,11 @@ module OperatorRecordable
|
|
31
31
|
m.__send__(:run_deleter_dsl, self, config)
|
32
32
|
m.__send__(:define_deleter_instance_methods, self, config)
|
33
33
|
end
|
34
|
+
|
35
|
+
if c.record_discarder?
|
36
|
+
m.__send__(:run_discarder_dsl, self, config)
|
37
|
+
m.__send__(:define_discarder_instance_methods, self, config)
|
38
|
+
end
|
34
39
|
end
|
35
40
|
end
|
36
41
|
|
@@ -49,6 +54,11 @@ module OperatorRecordable
|
|
49
54
|
run_add_association_dsl(:deleter, klass, config)
|
50
55
|
end
|
51
56
|
|
57
|
+
def run_discarder_dsl(klass, config)
|
58
|
+
klass.before_discard :"assign_#{config.discarder_association_name}"
|
59
|
+
run_add_association_dsl(:discarder, klass, config)
|
60
|
+
end
|
61
|
+
|
52
62
|
def run_add_association_dsl(type, klass, config)
|
53
63
|
klass.belongs_to config.association_name_for(type).to_sym,
|
54
64
|
config.operator_association_scope,
|
@@ -59,37 +69,48 @@ module OperatorRecordable
|
|
59
69
|
|
60
70
|
def define_creator_instance_methods(klass, config)
|
61
71
|
klass.class_eval <<~END_OF_DEF, __FILE__, __LINE__ + 1
|
62
|
-
private def assign_#{config.creator_association_name}
|
63
|
-
return unless (op = OperatorRecordable.operator)
|
64
|
-
|
65
|
-
self.#{config.creator_column_name} = op.id
|
66
|
-
end
|
72
|
+
private def assign_#{config.creator_association_name} # private def assign_creator
|
73
|
+
return unless (op = OperatorRecordable.operator) # return unless (op = OperatorRecordable.operator)
|
74
|
+
#
|
75
|
+
self.#{config.creator_column_name} = op.id # self.created_by = op.id
|
76
|
+
end # end
|
67
77
|
END_OF_DEF
|
68
78
|
end
|
69
79
|
|
70
80
|
def define_updater_instance_methods(klass, config)
|
71
81
|
klass.class_eval <<~END_OF_DEF, __FILE__, __LINE__ + 1
|
72
|
-
private def assign_#{config.updater_association_name}
|
73
|
-
return if !self.new_record? && !self.changed?
|
74
|
-
return unless (op = OperatorRecordable.operator)
|
75
|
-
|
76
|
-
self.#{config.updater_column_name} = op.id
|
77
|
-
end
|
82
|
+
private def assign_#{config.updater_association_name} # private def assign_updater
|
83
|
+
return if !self.new_record? && !self.changed? # return if !self.new_record? && !self.changed?
|
84
|
+
return unless (op = OperatorRecordable.operator) # return unless (op = OperatorRecordable.operator)
|
85
|
+
#
|
86
|
+
self.#{config.updater_column_name} = op.id # self.updated_by = op.id
|
87
|
+
end # end
|
78
88
|
END_OF_DEF
|
79
89
|
end
|
80
90
|
|
81
91
|
def define_deleter_instance_methods(klass, config)
|
82
92
|
klass.class_eval <<~END_OF_DEF, __FILE__, __LINE__ + 1
|
83
|
-
private def assign_#{config.deleter_association_name}
|
84
|
-
return if self.frozen?
|
85
|
-
return unless (op = OperatorRecordable.operator)
|
86
|
-
|
87
|
-
self
|
88
|
-
.class
|
89
|
-
.where(self.class.primary_key => id)
|
90
|
-
.update_all('#{config.deleter_column_name}' => op.id)
|
91
|
-
self.#{config.deleter_column_name} = op.id
|
92
|
-
end
|
93
|
+
private def assign_#{config.deleter_association_name} # private def assign_deleter
|
94
|
+
return if self.frozen? # return if self.frozen?
|
95
|
+
return unless (op = OperatorRecordable.operator) # return unless (op = OperatorRecordable.operator)
|
96
|
+
#
|
97
|
+
self # self
|
98
|
+
.class # .class
|
99
|
+
.where(self.class.primary_key => id) # .where(self.class.primary_key => id)
|
100
|
+
.update_all('#{config.deleter_column_name}' => op.id) # .update_all('deleted_by' => op.id)
|
101
|
+
self.#{config.deleter_column_name} = op.id # self.deleted_by = op.id
|
102
|
+
end # end
|
103
|
+
END_OF_DEF
|
104
|
+
end
|
105
|
+
|
106
|
+
def define_discarder_instance_methods(klass, config)
|
107
|
+
klass.class_eval <<~END_OF_DEF, __FILE__, __LINE__ + 1
|
108
|
+
private def assign_#{config.discarder_association_name} # private def assign_discarder
|
109
|
+
return if self.frozen? # return if self.frozen?
|
110
|
+
return unless (op = OperatorRecordable.operator) # return unless (op = OperatorRecordable.operator)
|
111
|
+
#
|
112
|
+
self.#{config.discarder_column_name} = op.id # self.discarded_by = op.id
|
113
|
+
end # end
|
93
114
|
END_OF_DEF
|
94
115
|
end
|
95
116
|
end
|
@@ -15,4 +15,4 @@ end
|
|
15
15
|
|
16
16
|
require "operator_recordable/store/thread_store"
|
17
17
|
require "operator_recordable/store/request_store" if defined? ::RequestStore
|
18
|
-
require "operator_recordable/store/current_attributes_store"
|
18
|
+
require "operator_recordable/store/current_attributes_store"
|
data/operator_recordable.gemspec
CHANGED
@@ -28,7 +28,7 @@ Gem::Specification.new do |spec| # rubocop:disable Metrics/BlockLength
|
|
28
28
|
|
29
29
|
spec.metadata["homepage_uri"] = spec.homepage
|
30
30
|
spec.metadata["source_code_uri"] = spec.homepage
|
31
|
-
spec.metadata["changelog_uri"] = "https://github.com/yujideveloper/operator_recordable/tree/
|
31
|
+
spec.metadata["changelog_uri"] = "https://github.com/yujideveloper/operator_recordable/tree/main/CHANGELOG.md"
|
32
32
|
|
33
33
|
spec.metadata["rubygems_mfa_required"] = "true"
|
34
34
|
|
@@ -46,9 +46,10 @@ Gem::Specification.new do |spec| # rubocop:disable Metrics/BlockLength
|
|
46
46
|
spec.add_dependency "activerecord", ">= 5.2"
|
47
47
|
spec.add_development_dependency "appraisal", ">= 2.3.0"
|
48
48
|
spec.add_development_dependency "bundler", ">= 1.16"
|
49
|
+
spec.add_development_dependency "discard", ">= 1.2"
|
49
50
|
spec.add_development_dependency "pry", ">= 0.10.0"
|
50
51
|
spec.add_development_dependency "rake", ">= 10.0"
|
51
52
|
spec.add_development_dependency "rspec", "~> 3.7"
|
52
|
-
spec.add_development_dependency "rubocop", ">=
|
53
|
+
spec.add_development_dependency "rubocop", ">= 1.13.0"
|
53
54
|
spec.add_development_dependency "sqlite3", ">= 1.3.13"
|
54
55
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: operator_recordable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yuji Hanamura
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-08-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '1.16'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: discard
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.2'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.2'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: pry
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -100,14 +114,14 @@ dependencies:
|
|
100
114
|
requirements:
|
101
115
|
- - ">="
|
102
116
|
- !ruby/object:Gem::Version
|
103
|
-
version:
|
117
|
+
version: 1.13.0
|
104
118
|
type: :development
|
105
119
|
prerelease: false
|
106
120
|
version_requirements: !ruby/object:Gem::Requirement
|
107
121
|
requirements:
|
108
122
|
- - ">="
|
109
123
|
- !ruby/object:Gem::Version
|
110
|
-
version:
|
124
|
+
version: 1.13.0
|
111
125
|
- !ruby/object:Gem::Dependency
|
112
126
|
name: sqlite3
|
113
127
|
requirement: !ruby/object:Gem::Requirement
|
@@ -169,9 +183,9 @@ metadata:
|
|
169
183
|
allowed_push_host: https://rubygems.org
|
170
184
|
homepage_uri: https://github.com/yujideveloper/operator_recordable
|
171
185
|
source_code_uri: https://github.com/yujideveloper/operator_recordable
|
172
|
-
changelog_uri: https://github.com/yujideveloper/operator_recordable/tree/
|
186
|
+
changelog_uri: https://github.com/yujideveloper/operator_recordable/tree/main/CHANGELOG.md
|
173
187
|
rubygems_mfa_required: 'true'
|
174
|
-
post_install_message:
|
188
|
+
post_install_message:
|
175
189
|
rdoc_options: []
|
176
190
|
require_paths:
|
177
191
|
- lib
|
@@ -186,8 +200,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
186
200
|
- !ruby/object:Gem::Version
|
187
201
|
version: '0'
|
188
202
|
requirements: []
|
189
|
-
rubygems_version: 3.
|
190
|
-
signing_key:
|
203
|
+
rubygems_version: 3.3.7
|
204
|
+
signing_key:
|
191
205
|
specification_version: 4
|
192
206
|
summary: OperatorRecordable is a Rails plugin to set created_by, updated_by, and deleted_by
|
193
207
|
to ActiveRecord objects.
|