operator_recordable 1.2.0 → 1.4.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
2
  SHA256:
3
- metadata.gz: ab283fd134cf058f9e80fd77978564891460512b16d25dcad77f36ce07675b6c
4
- data.tar.gz: fbfd74ee91030399f4637ab535ce38b7163b377a69cc9797b5261a211ee96b93
3
+ metadata.gz: 17d5261fe9e0dde7d722753e707a2a5210bc183866be7d9509b6670e2187e432
4
+ data.tar.gz: 7c569a64a127e3b293ac7d5ed66ba0762774163ef7395d16acd49bd7e30bba85
5
5
  SHA512:
6
- metadata.gz: d8777d0962188046f0cc556f1a9d399117d6a695b6f5b6e46d96b1cad036dd8de274cc6da2421788046e6dbe7fc5fde56169e75162767f77b3f513b75b1f8e58
7
- data.tar.gz: 052113312da2cacdd349e15c47b2c993baeb05c4b7f40f1b06f5cf83e8864015594dd54bffe75dea1946c18a5e4dd3d780f1695b0fe15809a40f60dd5fddb920
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/25)
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: :thread_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
@@ -2,6 +2,10 @@
2
2
 
3
3
  module OperatorRecordable
4
4
  class ThreadStore
5
+ def initialize
6
+ warn "DEPRECATION WARNING: `:thread_store` is deprecated. It will be removed in v2.0"
7
+ end
8
+
5
9
  def [](key)
6
10
  ::Thread.current[key]
7
11
  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" if defined? ::ActiveSupport::CurrentAttributes
18
+ require "operator_recordable/store/current_attributes_store"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module OperatorRecordable
4
- VERSION = "1.2.0"
4
+ VERSION = "1.4.0"
5
5
  end
@@ -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/master/CHANGELOG.md"
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", ">= 0.78.0"
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.2.0
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-04-26 00:00:00.000000000 Z
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: 0.78.0
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: 0.78.0
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/master/CHANGELOG.md
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.1.6
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.