rails_simple_event_sourcing 1.0.8 → 1.0.9
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/README.md +48 -31
- data/lib/rails_simple_event_sourcing/command_handler.rb +1 -1
- data/lib/rails_simple_event_sourcing/command_handlers/base.rb +3 -9
- data/lib/rails_simple_event_sourcing/commands/base.rb +0 -1
- data/lib/rails_simple_event_sourcing/result.rb +38 -1
- data/lib/rails_simple_event_sourcing/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2cdc3924ccf5cb03de4c576e06e36516187ab5743fdeacb7c4b543e1733af6ed
|
|
4
|
+
data.tar.gz: e8a6bcce2a7b918a9a55ffd37dcf11e31c4692c53678ae083a59213fdd39e29e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2825950884885d9366e2586ddada26b272fc9551ba92caefe9be08c78569ad5df7243bef7b6fcf51f3e6529fc93dba1b455aacb7e7ed61b94ce9c40bd9ac0868
|
|
7
|
+
data.tar.gz: b8b2ec4ceca8ace0ec9f51185ac373008c73a11c0aa536d650d844464822c2e4bf6aa919d797aff36807ceca23f366ebbadaf94dcd78230b0ace007d0efd33c6
|
data/README.md
CHANGED
|
@@ -173,15 +173,45 @@ Handlers can be discovered in two ways:
|
|
|
173
173
|
2. **Convention-based** - Using naming convention mapping (can be disabled via configuration)
|
|
174
174
|
|
|
175
175
|
**Result Object:**
|
|
176
|
-
The `Result`
|
|
176
|
+
The `Result` class has three fields:
|
|
177
177
|
- `success?` - Boolean indicating if the operation succeeded
|
|
178
178
|
- `data` - Data to return (usually the aggregate/model instance)
|
|
179
179
|
- `errors` - Array or hash of error messages when `success?` is false
|
|
180
180
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
181
|
+
Use the factory methods to build results:
|
|
182
|
+
|
|
183
|
+
```ruby
|
|
184
|
+
# Successful result
|
|
185
|
+
RailsSimpleEventSourcing::Result.success(data: customer)
|
|
186
|
+
|
|
187
|
+
# Failed result
|
|
188
|
+
RailsSimpleEventSourcing::Result.failure(errors: { email: ["already taken"] })
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
It supports a chainable API for use in controllers:
|
|
192
|
+
- `on_success { |data| }` - Executes the block (yielding `data`) if the result is successful
|
|
193
|
+
- `on_failure { |errors| }` - Executes the block (yielding `errors`) if the result failed
|
|
194
|
+
|
|
195
|
+
Both methods return `self`, so they can be chained. The predicate `success?` remains available for use in conditionals and tests.
|
|
196
|
+
|
|
197
|
+
```ruby
|
|
198
|
+
result = RailsSimpleEventSourcing::Result.success(data: customer)
|
|
199
|
+
|
|
200
|
+
# Chainable (preferred in controllers)
|
|
201
|
+
result
|
|
202
|
+
.on_success { |data| render json: data }
|
|
203
|
+
.on_failure { |errors| render json: { errors: }, status: :unprocessable_entity }
|
|
204
|
+
|
|
205
|
+
# Predicate (preferred in tests)
|
|
206
|
+
result.success? # => true
|
|
207
|
+
result.data # => #<Customer ...>
|
|
208
|
+
result.errors # => nil
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
**Helper Methods in Handlers:**
|
|
212
|
+
Inside a command handler, `success` and `failure` are delegated to `RailsSimpleEventSourcing::Result`:
|
|
213
|
+
- `success(data:)` - delegates to `RailsSimpleEventSourcing::Result.success`
|
|
214
|
+
- `failure(errors:)` - delegates to `RailsSimpleEventSourcing::Result.failure`
|
|
185
215
|
|
|
186
216
|
**Example - Basic Handler:**
|
|
187
217
|
|
|
@@ -198,11 +228,7 @@ class Customer
|
|
|
198
228
|
updated_at: Time.zone.now
|
|
199
229
|
)
|
|
200
230
|
|
|
201
|
-
|
|
202
|
-
success_result(data: event.aggregate)
|
|
203
|
-
|
|
204
|
-
# Or create Result directly
|
|
205
|
-
# RailsSimpleEventSourcing::Result.new(success?: true, data: event.aggregate)
|
|
231
|
+
success(data: event.aggregate)
|
|
206
232
|
end
|
|
207
233
|
end
|
|
208
234
|
end
|
|
@@ -224,11 +250,11 @@ class Customer
|
|
|
224
250
|
updated_at: Time.zone.now
|
|
225
251
|
)
|
|
226
252
|
|
|
227
|
-
|
|
253
|
+
success(data: event.aggregate)
|
|
228
254
|
rescue ActiveRecord::RecordNotUnique
|
|
229
|
-
|
|
255
|
+
failure(errors: ["Email has already been taken"])
|
|
230
256
|
rescue StandardError => e
|
|
231
|
-
|
|
257
|
+
failure(errors: ["An error occurred: #{e.message}"])
|
|
232
258
|
end
|
|
233
259
|
end
|
|
234
260
|
end
|
|
@@ -358,13 +384,10 @@ class CustomersController < ApplicationController
|
|
|
358
384
|
last_name: params[:last_name],
|
|
359
385
|
email: params[:email]
|
|
360
386
|
)
|
|
361
|
-
handler = RailsSimpleEventSourcing::CommandHandler.new(cmd).call
|
|
362
387
|
|
|
363
|
-
|
|
364
|
-
render json:
|
|
365
|
-
|
|
366
|
-
render json: { errors: handler.errors }, status: :unprocessable_entity
|
|
367
|
-
end
|
|
388
|
+
RailsSimpleEventSourcing::CommandHandler.new(cmd).call
|
|
389
|
+
.on_success { |data| render json: data }
|
|
390
|
+
.on_failure { |errors| render json: { errors: }, status: :unprocessable_entity }
|
|
368
391
|
end
|
|
369
392
|
end
|
|
370
393
|
```
|
|
@@ -382,13 +405,10 @@ class CustomersController < ApplicationController
|
|
|
382
405
|
last_name: params[:last_name],
|
|
383
406
|
email: params[:email]
|
|
384
407
|
)
|
|
385
|
-
handler = RailsSimpleEventSourcing::CommandHandler.new(cmd).call
|
|
386
408
|
|
|
387
|
-
|
|
388
|
-
render json:
|
|
389
|
-
|
|
390
|
-
render json: { errors: handler.errors }, status: :unprocessable_entity
|
|
391
|
-
end
|
|
409
|
+
RailsSimpleEventSourcing::CommandHandler.new(cmd).call
|
|
410
|
+
.on_success { |data| render json: data }
|
|
411
|
+
.on_failure { |errors| render json: { errors: }, status: :unprocessable_entity }
|
|
392
412
|
end
|
|
393
413
|
end
|
|
394
414
|
```
|
|
@@ -399,13 +419,10 @@ end
|
|
|
399
419
|
class CustomersController < ApplicationController
|
|
400
420
|
def destroy
|
|
401
421
|
cmd = Customer::Commands::Delete.new(aggregate_id: params[:id])
|
|
402
|
-
handler = RailsSimpleEventSourcing::CommandHandler.new(cmd).call
|
|
403
422
|
|
|
404
|
-
|
|
405
|
-
head :no_content
|
|
406
|
-
|
|
407
|
-
render json: { errors: handler.errors }, status: :unprocessable_entity
|
|
408
|
-
end
|
|
423
|
+
RailsSimpleEventSourcing::CommandHandler.new(cmd).call
|
|
424
|
+
.on_success { head :no_content }
|
|
425
|
+
.on_failure { |errors| render json: { errors: }, status: :unprocessable_entity }
|
|
409
426
|
end
|
|
410
427
|
end
|
|
411
428
|
```
|
|
@@ -3,20 +3,14 @@
|
|
|
3
3
|
module RailsSimpleEventSourcing
|
|
4
4
|
module CommandHandlers
|
|
5
5
|
class Base
|
|
6
|
+
delegate :success, :failure, to: 'RailsSimpleEventSourcing::Result'
|
|
7
|
+
|
|
6
8
|
def initialize(command:)
|
|
7
9
|
@command = command
|
|
8
10
|
end
|
|
9
11
|
|
|
10
12
|
def call
|
|
11
|
-
raise
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def success_result(data: nil)
|
|
15
|
-
RailsSimpleEventSourcing::Result.new(success?: true, data:)
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def failure_result(errors:)
|
|
19
|
-
RailsSimpleEventSourcing::Result.new(success?: false, errors:)
|
|
13
|
+
raise NotImplementedError, "You must implement #{self.class}#call"
|
|
20
14
|
end
|
|
21
15
|
end
|
|
22
16
|
end
|
|
@@ -1,5 +1,42 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module RailsSimpleEventSourcing
|
|
4
|
-
Result
|
|
4
|
+
class Result
|
|
5
|
+
attr_reader :data, :errors
|
|
6
|
+
|
|
7
|
+
def self.success(data: nil)
|
|
8
|
+
new(success: true, data:)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def self.failure(errors:)
|
|
12
|
+
new(success: false, errors:)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def initialize(success:, data: nil, errors: nil)
|
|
16
|
+
raise ArgumentError, 'Successful result cannot have errors' if success && errors
|
|
17
|
+
raise ArgumentError, 'Failed result cannot have data' if !success && data
|
|
18
|
+
|
|
19
|
+
@success = success
|
|
20
|
+
@data = data
|
|
21
|
+
@errors = errors
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def success?
|
|
25
|
+
@success
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def on_success(&block)
|
|
29
|
+
raise ArgumentError, 'Block required' unless block
|
|
30
|
+
|
|
31
|
+
block.call(data) if success?
|
|
32
|
+
self
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def on_failure(&block)
|
|
36
|
+
raise ArgumentError, 'Block required' unless block
|
|
37
|
+
|
|
38
|
+
block.call(errors) unless success?
|
|
39
|
+
self
|
|
40
|
+
end
|
|
41
|
+
end
|
|
5
42
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rails_simple_event_sourcing
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.0.
|
|
4
|
+
version: 1.0.9
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Damian Baćkowski
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-03-01 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: pg
|