operator_recordable 1.2.0 → 1.3.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 +16 -1
- data/README.md +7 -2
- data/lib/operator_recordable/configuration.rb +9 -3
- data/lib/operator_recordable/recorder.rb +46 -21
- data/lib/operator_recordable/store.rb +1 -1
- data/lib/operator_recordable/version.rb +1 -1
- data/operator_recordable.gemspec +2 -1
- metadata +18 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f15fe7bfab329bcdac169e462ecfdb78af6c49a18e851c904ef9e16a8b33ac4c
|
|
4
|
+
data.tar.gz: 60a6488ec7540f1b7ea60173126a4817b9ae139058cddfec0e34999adac33244
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2ad18e622600bd8ba978d998f24ab6b5aa25cd9763159d290b27e9e6b8003715229239da507364ddb083bbc0a03e9ecaa87acc947743aa16e9087ae36dee4853
|
|
7
|
+
data.tar.gz: f32382da136939d9cad3d9bce663886ae116e6006b0235d7196a567f4830e67ececc1af2bef838f96ec7d386b604195e4c92549a1ad7155ac54d8282531bbb58
|
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,27 @@
|
|
|
1
1
|
## Unreleased
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
## 1.3.0 (2022-06-01)
|
|
5
|
+
|
|
6
|
+
### Changes
|
|
7
|
+
|
|
8
|
+
* Support discard gem for soft deletes
|
|
9
|
+
+ [PR#31](https://github.com/yujideveloper/operator_recordable/pull/31)
|
|
10
|
+
* Get rid of needless guard clauses for ActiveSupport 5.1 and older
|
|
11
|
+
+ [PR#32](https://github.com/yujideveloper/operator_recordable/pull/32)
|
|
12
|
+
|
|
13
|
+
### Misc
|
|
14
|
+
|
|
15
|
+
* Fix RuboCop offenses
|
|
16
|
+
+ [PR#33](https://github.com/yujideveloper/operator_recordable/pull/33)
|
|
17
|
+
|
|
18
|
+
|
|
4
19
|
## 1.2.0 (2022-04-26)
|
|
5
20
|
|
|
6
21
|
### Changes
|
|
7
22
|
|
|
8
23
|
* Make associations optional
|
|
9
|
-
+ [PR#28](https://github.com/yujideveloper/operator_recordable/pull/
|
|
24
|
+
+ [PR#28](https://github.com/yujideveloper/operator_recordable/pull/28)
|
|
10
25
|
|
|
11
26
|
### Misc
|
|
12
27
|
|
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,9 +40,11 @@ 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
50
|
store: :thread_store
|
|
@@ -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` |
|
|
@@ -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,52 @@ 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 # self
|
|
113
|
+
.class # .class
|
|
114
|
+
.where(self.class.primary_key => id) # .where(self.class.primary_key => id)
|
|
115
|
+
.update_all('#{config.discarder_column_name}' => op.id) # .update_all('discarded_by' => op.id)
|
|
116
|
+
self.#{config.discarder_column_name} = op.id # self.discarded_by = op.id
|
|
117
|
+
end # end
|
|
93
118
|
END_OF_DEF
|
|
94
119
|
end
|
|
95
120
|
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
|
@@ -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.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Yuji Hanamura
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2022-
|
|
11
|
+
date: 2022-06-01 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
|