eventsimple 2.6.0 → 2.7.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 64f15c989c426a973f8d1689e098c0ea7947af521742bb8e70badf2b705ed162
4
- data.tar.gz: 48de4621966b60aa7328e4eb51c383d2cb65a5862ce8301d9d754eca6cbc0d3e
3
+ metadata.gz: 44d245e314a08957bc83a97a929c2b8843966f5f435c91719c15d432a5437c9f
4
+ data.tar.gz: 9a6470ff2078eaae9a1d7b290d7e31277bd68f10f773cbed710a8581c3edf85d
5
5
  SHA512:
6
- metadata.gz: 6c0a3945fd3e5dc70798933b0058d91c79cea258ecbb895917e6f93a9d6e3cf404bd356f36332d8e072b2dcb7a4bdbb32b560696af4266e592bf34e115200904
7
- data.tar.gz: d1f53a2cbdbe9f3c951368d52300db2e3fc692f2b9e76d39c179d8f37675e5ff6ff7735643e480b1b68c748bdc2cd8a6c0a2cbbd9e330827f2078b3b253ab5d4
6
+ metadata.gz: b8458ce8ae73209f1724a825da379f49b5954353b63dbe48c79fc10802cc1667300314cfbd6defc32a07e482b39698fd32439c2acac8ee22df0e6702a5c2439e
7
+ data.tar.gz: 633b6e1d896e7f113574e36fcb57507a7977e3acf71d90a08a0bb6161c63257069fb5639ee88386a76d3bb93e056b24971607a511534ec028f2a068be9b2ab62
data/CHANGELOG.md CHANGED
@@ -6,6 +6,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6
6
 
7
7
  ## Unreleased
8
8
 
9
+ ## 2.7.0 - 2026-05-03
10
+ ### Removed
11
+ - Reverted the readonly-bypass enforcement and `Eventsimple.enable_writes! { }` API
12
+ introduced in 2.5.0. Persistence bypass methods (`delete`, `update_column(s)`,
13
+ `update_attribute(!)`, `touch`, `toggle!`, `increment!`, `decrement!`) and
14
+ relation-level bulk SQL (`insert*`, `upsert*`, `update_all`, `delete_all`,
15
+ `touch_all`) no longer raise `ActiveRecord::ReadOnlyRecord` on event-sourced
16
+ models. Model instance `#enable_writes!` is restored.
17
+
9
18
  ## 2.6.0 - 2026-05-01
10
19
  ### Added
11
20
  - `Eventsimple::Types::*.encrypted` now accepts an optional
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- eventsimple (2.6.0)
4
+ eventsimple (2.7.0)
5
5
  concurrent-ruby (>= 1.2.3)
6
6
  dry-struct (>= 1.8.0)
7
7
  dry-types (>= 1.7.0)
@@ -458,7 +458,7 @@ CHECKSUMS
458
458
  dry-types (1.9.0) sha256=7b656fe0a78d2432500ae1f29fefd6762f5a032ca7000e4f36bc111453d45d4d
459
459
  erb (6.0.1) sha256=28ecdd99c5472aebd5674d6061e3c6b0a45c049578b071e5a52c2a7f13c197e5
460
460
  erubi (1.13.1) sha256=a082103b0885dbc5ecf1172fede897f9ebdb745a4b97a5e8dc63953db1ee4ad9
461
- eventsimple (2.6.0)
461
+ eventsimple (2.7.0)
462
462
  factory_bot (6.5.6) sha256=12beb373214dccc086a7a63763d6718c49769d5606f0501e0a4442676917e077
463
463
  factory_bot_rails (6.5.1) sha256=d3cc4851eae4dea8a665ec4a4516895045e710554d2b5ac9e68b94d351bc6d68
464
464
  ffi (1.17.3-aarch64-linux-gnu) sha256=28ad573df26560f0aedd8a90c3371279a0b2bd0b4e834b16a2baa10bd7a97068
@@ -25,7 +25,7 @@ module Eventsimple
25
25
  has_many :events, class_name: event_klass.name.to_s,
26
26
  foreign_key: :aggregate_id,
27
27
  primary_key: aggregate_id,
28
- dependent: :restrict_with_exception,
28
+ dependent: :delete_all,
29
29
  inverse_of: model_name.element.to_sym,
30
30
  autosave: false,
31
31
  validate: false
@@ -45,11 +45,8 @@ module Eventsimple
45
45
 
46
46
  Eventsimple.configuration.ui_visible_model_names |= [name]
47
47
 
48
- include Readonly
49
48
  include InstanceMethods
50
49
  extend ClassMethods
51
-
52
- Readonly.install_relation_guards!(self)
53
50
  end
54
51
 
55
52
  module InstanceMethods
@@ -59,6 +56,16 @@ module Eventsimple
59
56
  attributes == reprojected.attributes
60
57
  end
61
58
 
59
+ def enable_writes!(&block)
60
+ was_readonly = @readonly
61
+ @readonly = false
62
+
63
+ return unless block
64
+
65
+ yield self
66
+ @readonly = was_readonly
67
+ end
68
+
62
69
  def reproject(at: nil, skip_deleted: false)
63
70
  event_history = at ? events.where('created_at <= ?', at).load : events.load
64
71
 
@@ -75,11 +75,8 @@ module Eventsimple
75
75
  after_create :dispatch
76
76
  after_create :readonly!
77
77
 
78
- include Readonly
79
78
  include InstanceMethods
80
79
  extend ClassMethods
81
-
82
- Readonly.install_relation_guards!(self)
83
80
  end
84
81
 
85
82
  module InstanceMethods
@@ -126,9 +123,8 @@ module Eventsimple
126
123
  apply_timestamps(aggregate)
127
124
  apply(aggregate)
128
125
 
129
- Eventsimple.enable_writes! do
130
- aggregate.save!
131
- end
126
+ aggregate.enable_writes!
127
+ aggregate.save!
132
128
  aggregate.readonly!
133
129
 
134
130
  self.aggregate = aggregate
@@ -145,6 +141,16 @@ module Eventsimple
145
141
  def aggregate=(aggregate)
146
142
  public_send(:"#{_aggregate_klass.model_name.element}=", aggregate)
147
143
  end
144
+
145
+ def enable_writes!(&block)
146
+ was_readonly = @readonly
147
+ @readonly = false
148
+
149
+ return unless block
150
+
151
+ yield self
152
+ @readonly = was_readonly
153
+ end
148
154
  end
149
155
 
150
156
  module ClassMethods
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Eventsimple
4
- VERSION = '2.6.0'
4
+ VERSION = '2.7.0'
5
5
  end
data/lib/eventsimple.rb CHANGED
@@ -21,7 +21,6 @@ require 'eventsimple/event_dispatcher'
21
21
  require 'eventsimple/reactor'
22
22
  require 'eventsimple/invalid_transition'
23
23
 
24
- require 'eventsimple/readonly'
25
24
  require 'eventsimple/entity'
26
25
  require 'eventsimple/event'
27
26
 
@@ -37,11 +36,5 @@ module Eventsimple
37
36
  def configure
38
37
  yield(configuration)
39
38
  end
40
-
41
- # Unlocks writes for event-sourced models for the duration of the block (instance +save+,
42
- # relation +update_all+, +upsert+, +delete_all+, etc.).
43
- def enable_writes!(&block)
44
- Readonly.enable_writes!(&block)
45
- end
46
39
  end
47
40
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: eventsimple
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.6.0
4
+ version: 2.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Zulfiqar Ali
@@ -363,7 +363,6 @@ files:
363
363
  - lib/eventsimple/outbox/models/cursor.rb
364
364
  - lib/eventsimple/reactor.rb
365
365
  - lib/eventsimple/reactor_worker.rb
366
- - lib/eventsimple/readonly.rb
367
366
  - lib/eventsimple/support/spec_helpers.rb
368
367
  - lib/eventsimple/types.rb
369
368
  - lib/eventsimple/types/encrypted_type.rb
@@ -1,116 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Eventsimple
4
- # Raised when +#enable_writes!+ is called on a model instance. Use
5
- # {Eventsimple.enable_writes!} instead.
6
- DeprecatedInstanceEnableWrites = Class.new(StandardError)
7
-
8
- # Closes gaps where writes bypass +readonly!+ (instance helpers like +delete+,
9
- # +update_column+, relation SQL like +upsert+ / +delete_all+ / +update_all+).
10
- # Raises +ActiveRecord::ReadOnlyRecord+ unless {Eventsimple.enable_writes!} is active.
11
- module Readonly
12
- THREAD_KEY = :eventsimple_class_writes_depth
13
-
14
- module RelationMethods
15
- RELATION_WRITE_METHODS = %i[
16
- insert insert!
17
- insert_all insert_all!
18
- upsert upsert_all
19
- update_all delete_all touch_all
20
- ].freeze
21
-
22
- RELATION_WRITE_METHODS.each do |method_name|
23
- define_method(method_name) do |*args, **kwargs, &block|
24
- _raise_relation_readonly! unless Readonly.class_writes_enabled?
25
- super(*args, **kwargs, &block)
26
- end
27
- end
28
-
29
- private
30
-
31
- def _raise_relation_readonly!
32
- raise ActiveRecord::ReadOnlyRecord, "#{model.name} is marked as readonly"
33
- end
34
- end
35
-
36
- class << self
37
- def install_relation_guards!(model_class)
38
- ActiveRecord::Delegation.delegated_classes.each do |relation_base|
39
- delegate_class = model_class.relation_delegate_class(relation_base)
40
- next if delegate_class.ancestors.include?(RelationMethods)
41
-
42
- delegate_class.prepend(RelationMethods)
43
- end
44
- end
45
-
46
- def enable_writes!
47
- Thread.current[THREAD_KEY] = Thread.current[THREAD_KEY].to_i + 1
48
- yield
49
- ensure
50
- d = Thread.current[THREAD_KEY].to_i - 1
51
- Thread.current[THREAD_KEY] = d.positive? ? d : nil
52
- end
53
-
54
- def class_writes_enabled?
55
- Thread.current[THREAD_KEY].to_i.positive?
56
- end
57
- end
58
-
59
- def readonly?
60
- return false if Readonly.class_writes_enabled?
61
-
62
- super
63
- end
64
-
65
- def enable_writes!(&_block)
66
- raise DeprecatedInstanceEnableWrites, <<~MSG.squish
67
- Use Eventsimple.enable_writes! { ... } instead of #{self.class.name}#enable_writes!
68
- MSG
69
- end
70
-
71
- def delete
72
- _raise_readonly_record_error if readonly?
73
- super
74
- end
75
-
76
- def update_column(...)
77
- _raise_readonly_record_error if readonly?
78
- super
79
- end
80
-
81
- def update_columns(...)
82
- _raise_readonly_record_error if readonly?
83
- super
84
- end
85
-
86
- def update_attribute(...)
87
- _raise_readonly_record_error if readonly?
88
- super
89
- end
90
-
91
- def update_attribute!(...)
92
- _raise_readonly_record_error if readonly?
93
- super
94
- end
95
-
96
- def increment!(...)
97
- _raise_readonly_record_error if readonly?
98
- super
99
- end
100
-
101
- def decrement!(...)
102
- _raise_readonly_record_error if readonly?
103
- super
104
- end
105
-
106
- def toggle!(...)
107
- _raise_readonly_record_error if readonly?
108
- super
109
- end
110
-
111
- def touch(...)
112
- _raise_readonly_record_error if readonly?
113
- super
114
- end
115
- end
116
- end