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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3de0a8a9ff2169679636b2f07ecbeb3c665bfd6a7167f564029c343d508dbcc0
4
- data.tar.gz: 136e1bb962428462dd0921cefa63746beefb6efab578f6c8a0e018709f10da1f
3
+ metadata.gz: 2cdc3924ccf5cb03de4c576e06e36516187ab5743fdeacb7c4b543e1733af6ed
4
+ data.tar.gz: e8a6bcce2a7b918a9a55ffd37dcf11e31c4692c53678ae083a59213fdd39e29e
5
5
  SHA512:
6
- metadata.gz: fcd653bc3201aeb4cffca05df6f9819e3b8d9ee2eab08e60e35988438321bf6f6b15fb7d65d0940483f9087877f5f451645fc26f7e1fb31fb36e61a898760aee
7
- data.tar.gz: 85449f552f258d5d2ccd43f238389769dafdf885d93beeb7f1e4f47280f1bbc9ab5acb8fa435e94a3ca9f0602af52677812f1c8dcffa85857277b977081f0fb7
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` struct has three fields:
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
- **Helper Methods:**
182
- The base class provides convenience methods:
183
- - `success_result(data:)` - Creates a successful result
184
- - `failure_result(errors:)` - Creates a failed result
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
- # Using helper method (recommended)
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
- success_result(data: event.aggregate)
253
+ success(data: event.aggregate)
228
254
  rescue ActiveRecord::RecordNotUnique
229
- failure_result(errors: ["Email has already been taken"])
255
+ failure(errors: ["Email has already been taken"])
230
256
  rescue StandardError => e
231
- failure_result(errors: ["An error occurred: #{e.message}"])
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
- if handler.success?
364
- render json: handler.data
365
- else
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
- if handler.success?
388
- render json: handler.data
389
- else
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
- if handler.success?
405
- head :no_content
406
- else
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
  ```
@@ -9,7 +9,7 @@ module RailsSimpleEventSourcing
9
9
  end
10
10
 
11
11
  def call
12
- return Result.new(success?: false, errors: @command.errors) unless @command.valid?
12
+ return Result.failure(errors: @command.errors) unless @command.valid?
13
13
 
14
14
  initialize_command_handler.call
15
15
  end
@@ -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 NoMethodError, "You must implement #{self.class}#call"
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
@@ -4,7 +4,6 @@ module RailsSimpleEventSourcing
4
4
  module Commands
5
5
  class Base
6
6
  include ActiveModel::Model
7
- include ActiveModel::Validations
8
7
 
9
8
  attr_accessor :aggregate_id
10
9
  end
@@ -1,5 +1,42 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RailsSimpleEventSourcing
4
- Result = Struct.new(:success?, :data, :errors, keyword_init: true)
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RailsSimpleEventSourcing
4
- VERSION = '1.0.8'
4
+ VERSION = '1.0.9'
5
5
  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.8
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-02-26 00:00:00.000000000 Z
11
+ date: 2026-03-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pg