attribute_guard 1.1.0 → 1.1.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fa71cf702b0f01ded796adf8ba3f215d024cf7a7947d633450213266df33cd74
4
- data.tar.gz: 96bb1d220b952c302e9c749378be645c47fa66f49a0860d8b110ce49d2d1f0cb
3
+ metadata.gz: 88ec907e7391560c5a2690875407a3caa1ba387c6b52896d222d17964babcec9
4
+ data.tar.gz: 909244a8bc6e31c80574f27923e88f76b94e7a16720c75878b1ab83bf2b560f0
5
5
  SHA512:
6
- metadata.gz: 574fcacc35b3a9c4029999e6e9a8c89ae8d35c1f22e6187ebafbea27079e0f812a23bbf93fb42ccd667f570fa3060fba6f3bdc6e2fc1a3411bccb4066345710e
7
- data.tar.gz: f3b1df97332fdfeed565332fb0be50a53811e95d3661ee0ca1988406ffe690e9cca734a2b6a136d4eacaddf2b995cf9d6c8eaa18d1647aa52ce39e6d96606c49
6
+ metadata.gz: d00b0a3d6cee7b7cf3aa246129214dad28218536284a6d411aebd718711aed7f381921a6d5db196e02a89e9377f902fc096440efef218d93f3e94ed99f0e09bb
7
+ data.tar.gz: 0a378c08a53d9b858581739ccdcec49a06d75ec1df1dd49681ea50a979d848abebe16a6087cbe669048c69dd714ba665e50fd835978b6c6b974943b217cf0756
data/CHANGELOG.md CHANGED
@@ -4,6 +4,19 @@ All notable changes to this project will be documented in this file.
4
4
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5
5
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## 1.1.1
8
+
9
+ ### Fixed
10
+
11
+ - Fixed keyword arguments not being forwarded through the prepended constructor, which raised an `ArgumentError` when including `AttributeGuard` in a class whose `initialize` method takes keyword arguments.
12
+ - `unlock_attributes` now returns the record when called with an empty attribute list instead of `nil` so method chaining works as documented.
13
+ - Unlocked attributes are no longer shared between a record and its `dup` or `clone`; unlocking attributes on a copy no longer unlocks them on the original.
14
+ - `lock_attributes` now raises an `ArgumentError` if an invalid mode is specified instead of silently treating it as `:error`.
15
+
16
+ ### Changed
17
+
18
+ - Minimum required Ruby version is now 2.6.
19
+
7
20
  ## 1.1.0
8
21
 
9
22
  ### Added
data/README.md CHANGED
@@ -126,7 +126,7 @@ class MyModel
126
126
  include AttributeGuard
127
127
 
128
128
  lock_attributes :email, mode: :error
129
- lock_attributes :name: mode: :warn
129
+ lock_attributes :name, mode: :warn
130
130
  lock_attributes :updated_at, mode: :raise
131
131
  lock_attributes :created_at, mode: ->(record, attribute) { raise "Created timestamp cannot be changed" }
132
132
  end
@@ -140,6 +140,10 @@ end
140
140
 
141
141
  * `Proc` - If you provide a `Proc` object, it will be called with the record and the attribute name when a locked attribute is changed.
142
142
 
143
+ ### Thread Safety
144
+
145
+ Unlocked attributes are tracked per model instance. Like ActiveRecord models in general, individual record instances are not thread safe, so you should not share a record between threads while unlocking attributes on it.
146
+
143
147
  ### Using with ActiveModel
144
148
 
145
149
  The gem works out of the box with ActiveRecord. You can also use it with ActiveModel classes as long as they include the `ActiveModel::Validations` and `ActiveModel::Dirty` modules. The model also needs to implement a `new_record?` method.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.1.0
1
+ 1.1.1
@@ -9,6 +9,12 @@ Gem::Specification.new do |spec|
9
9
  spec.homepage = "https://github.com/bdurand/attribute_guard"
10
10
  spec.license = "MIT"
11
11
 
12
+ spec.metadata = {
13
+ "homepage_uri" => spec.homepage,
14
+ "source_code_uri" => spec.homepage,
15
+ "changelog_uri" => "#{spec.homepage}/blob/main/CHANGELOG.md"
16
+ }
17
+
12
18
  # Specify which files should be added to the gem when it is released.
13
19
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
14
20
  ignore_files = %w[
@@ -29,7 +35,7 @@ Gem::Specification.new do |spec|
29
35
 
30
36
  spec.require_paths = ["lib"]
31
37
 
32
- spec.required_ruby_version = ">= 2.5"
38
+ spec.required_ruby_version = ">= 2.6"
33
39
 
34
40
  spec.add_dependency "activemodel", ">= 5.2"
35
41
 
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "set"
4
+
3
5
  require "active_support/concern"
4
6
  require "active_support/lazy_load_hooks"
5
7
  require "active_model/validator"
@@ -50,7 +52,7 @@ module AttributeGuard
50
52
  end
51
53
 
52
54
  module Initializer
53
- def initialize(*)
55
+ def initialize(*args, **kwargs)
54
56
  @unlocked_attributes = nil
55
57
  super
56
58
  end
@@ -65,8 +67,9 @@ module AttributeGuard
65
67
 
66
68
  return if record.new_record?
67
69
 
70
+ changes = record.changes
68
71
  record.class.send(:locked_attributes).each do |attribute, params|
69
- if record.changes.include?(attribute) && record.attribute_locked?(attribute)
72
+ if changes.include?(attribute) && record.attribute_locked?(attribute)
70
73
  message, mode = params
71
74
  if mode == :warn
72
75
  log_warning(record, attribute)
@@ -110,6 +113,10 @@ module AttributeGuard
110
113
  # @param mode [Symbol, Proc] mode to use when a locked attribute is changed
111
114
  # @return [void]
112
115
  def lock_attributes(*attributes, error: :locked, mode: :error)
116
+ unless mode == :error || mode == :warn || mode == :raise || mode.respond_to?(:call)
117
+ raise ArgumentError.new("Invalid mode: #{mode.inspect}")
118
+ end
119
+
113
120
  locked = locked_attributes.dup
114
121
  error = error.dup.freeze if error.is_a?(String)
115
122
 
@@ -140,7 +147,7 @@ module AttributeGuard
140
147
  # @return [Object] the object itself
141
148
  def unlock_attributes(*attributes)
142
149
  attributes = attributes.flatten.map(&:to_s)
143
- return if attributes.empty?
150
+ return self if attributes.empty?
144
151
 
145
152
  @unlocked_attributes ||= Set.new
146
153
 
@@ -154,7 +161,7 @@ module AttributeGuard
154
161
  clear_unlocked_attributes if @unlocked_attributes.empty?
155
162
  end
156
163
  else
157
- @unlocked_attributes.merge(attributes)
164
+ @unlocked_attributes = @unlocked_attributes.dup.merge(attributes)
158
165
  end
159
166
 
160
167
  self
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: attribute_guard
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian Durand
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2024-04-03 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: activemodel
@@ -38,7 +37,6 @@ dependencies:
38
37
  - - ">="
39
38
  - !ruby/object:Gem::Version
40
39
  version: '0'
41
- description:
42
40
  email:
43
41
  - bbdurand@gmail.com
44
42
  executables: []
@@ -55,8 +53,10 @@ files:
55
53
  homepage: https://github.com/bdurand/attribute_guard
56
54
  licenses:
57
55
  - MIT
58
- metadata: {}
59
- post_install_message:
56
+ metadata:
57
+ homepage_uri: https://github.com/bdurand/attribute_guard
58
+ source_code_uri: https://github.com/bdurand/attribute_guard
59
+ changelog_uri: https://github.com/bdurand/attribute_guard/blob/main/CHANGELOG.md
60
60
  rdoc_options: []
61
61
  require_paths:
62
62
  - lib
@@ -64,15 +64,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
64
64
  requirements:
65
65
  - - ">="
66
66
  - !ruby/object:Gem::Version
67
- version: '2.5'
67
+ version: '2.6'
68
68
  required_rubygems_version: !ruby/object:Gem::Requirement
69
69
  requirements:
70
70
  - - ">="
71
71
  - !ruby/object:Gem::Version
72
72
  version: '0'
73
73
  requirements: []
74
- rubygems_version: 3.4.12
75
- signing_key:
74
+ rubygems_version: 4.0.3
76
75
  specification_version: 4
77
76
  summary: ActiveRecord/ActiveModel extension that allows locking attributes to prevent
78
77
  unintended updates.