aggregate_root 0.3.6 → 0.4.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 +4 -4
- data/CHANGELOG.md +7 -2
- data/CONTRIBUTING.md +1 -1
- data/README.md +13 -26
- data/lib/aggregate_root.rb +40 -2
- data/lib/aggregate_root/default_apply_strategy.rb +1 -1
- data/lib/aggregate_root/version.rb +1 -1
- metadata +2 -4
- data/lib/aggregate_root/base.rb +0 -35
- data/lib/aggregate_root/repository.rb +0 -26
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: e5827865ed26ac8902ec51ad07999dfe644a7e6a
         | 
| 4 | 
            +
              data.tar.gz: 85677640dc2d4062ab2e63e092db7a8afad77c9e
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 1c09676af689188c5a282b6a96197687eb209aeb7fb4120907845a12dea2cdafd5063b6802f77bd0515f41f9012f3a40b891b20d3ec834679ab6f77e4da74684
         | 
| 7 | 
            +
              data.tar.gz: 773e80cd3444a43139efdef6f0fb7df20e1db9d00c17abb19c9255d49396d49e11b51c527be6dc67c9212bcbbbeca6d58848304c5a02a9747658e66278c5f536
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -1,3 +1,8 @@ | |
| 1 | 
            +
            ### 0.4.0 (28.10.2016)
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            * Change: redesign whole gem from scratch making it easier to use
         | 
| 4 | 
            +
                      This is a breaking change!
         | 
| 5 | 
            +
             | 
| 1 6 | 
             
            ### 0.3.6 (18.10.2016)
         | 
| 2 7 |  | 
| 3 8 | 
             
            * Change: ruby_event_store updated to 0.13.0
         | 
| @@ -21,11 +26,11 @@ | |
| 21 26 | 
             
            ### 0.3.1 (24.06.2016)
         | 
| 22 27 |  | 
| 23 28 | 
             
            * Change: ruby_event_store updated to 0.9.0
         | 
| 24 | 
            -
            * Fix: Clarify Licensing terms - MIT  | 
| 29 | 
            +
            * Fix: Clarify Licensing terms - MIT license it is from now
         | 
| 25 30 |  | 
| 26 31 | 
             
            ### 0.3.0 (21.06.2016)
         | 
| 27 32 |  | 
| 28 | 
            -
            * Change: Replace RailsEventStore dependency with  | 
| 33 | 
            +
            * Change: Replace RailsEventStore dependency with more generic RubyEventStore
         | 
| 29 34 |  | 
| 30 35 | 
             
            ### 0.2.1 (21.03.2016)
         | 
| 31 36 |  | 
    
        data/CONTRIBUTING.md
    CHANGED
    
    | @@ -16,7 +16,7 @@ Any kind of contribution is welcomed. Here is a few guidelines that we need cont | |
| 16 16 | 
             
            ## Making Changes
         | 
| 17 17 |  | 
| 18 18 | 
             
            * Create a feature branch from where you want to base your work.
         | 
| 19 | 
            -
            * Do your work. Please try to keep your commits small and  | 
| 19 | 
            +
            * Do your work. Please try to keep your commits small and focused.
         | 
| 20 20 | 
             
            * Make sure you have added the necessary tests for your changes.
         | 
| 21 21 | 
             
            * Push your changes to a feature branch in your fork of the repository.
         | 
| 22 22 | 
             
            * Submit a pull request to the AggregateRoot repository.
         | 
    
        data/README.md
    CHANGED
    
    | @@ -27,13 +27,7 @@ AggregateRoot.configure do |config| | |
| 27 27 | 
             
            end
         | 
| 28 28 | 
             
            ```
         | 
| 29 29 |  | 
| 30 | 
            -
            Remember that this is only a default event store used by `AggregateRoot | 
| 31 | 
            -
            You could always set any event store client (must match interface) when creating `AggregateRoot::Repository`.
         | 
| 32 | 
            -
             | 
| 33 | 
            -
            ```ruby
         | 
| 34 | 
            -
            repository = AggregateRoot::Repository.new(YourOwnEventStore.new)
         | 
| 35 | 
            -
            # do you work here...
         | 
| 36 | 
            -
            ```
         | 
| 30 | 
            +
            Remember that this is only a default event store used by `AggregateRoot` module when no event store is given in `load` / `store` methods parameters.
         | 
| 37 31 |  | 
| 38 32 | 
             
            To use [RailsEventStore](https://github.com/arkency/rails_event_store/) add to Gemfile:
         | 
| 39 33 |  | 
| @@ -51,12 +45,7 @@ It is important to assign `id` at initializer - it will be used as a event store | |
| 51 45 |  | 
| 52 46 | 
             
            ```ruby
         | 
| 53 47 | 
             
            class Order
         | 
| 54 | 
            -
              include AggregateRoot | 
| 55 | 
            -
             | 
| 56 | 
            -
              def initialize(id = generate_id)
         | 
| 57 | 
            -
                self.id = id
         | 
| 58 | 
            -
                # any other code here
         | 
| 59 | 
            -
              end
         | 
| 48 | 
            +
              include AggregateRoot
         | 
| 60 49 |  | 
| 61 50 | 
             
              # ... more later
         | 
| 62 51 | 
             
            end
         | 
| @@ -71,12 +60,11 @@ OrderExpired   = Class.new(RailsEventStore::Event) | |
| 71 60 |  | 
| 72 61 | 
             
            ```ruby
         | 
| 73 62 | 
             
            class Order
         | 
| 74 | 
            -
              include AggregateRoot | 
| 63 | 
            +
              include AggregateRoot
         | 
| 75 64 | 
             
              HasBeenAlreadySubmitted = Class.new(StandardError)
         | 
| 76 65 | 
             
              HasExpired              = Class.new(StandardError)
         | 
| 77 66 |  | 
| 78 | 
            -
              def initialize | 
| 79 | 
            -
                self.id = id
         | 
| 67 | 
            +
              def initialize
         | 
| 80 68 | 
             
                self.state = :new
         | 
| 81 69 | 
             
                # any other code here
         | 
| 82 70 | 
             
              end
         | 
| @@ -84,7 +72,7 @@ class Order | |
| 84 72 | 
             
              def submit
         | 
| 85 73 | 
             
                raise HasBeenAlreadySubmitted if state == :submitted
         | 
| 86 74 | 
             
                raise HasExpired if state == :expired
         | 
| 87 | 
            -
                apply OrderSubmitted.new(delivery_date: Time.now + 24.hours)
         | 
| 75 | 
            +
                apply OrderSubmitted.new(data: {delivery_date: Time.now + 24.hours})
         | 
| 88 76 | 
             
              end
         | 
| 89 77 |  | 
| 90 78 | 
             
              def expire
         | 
| @@ -107,9 +95,8 @@ end | |
| 107 95 | 
             
            #### Loading an aggregate root object from event store
         | 
| 108 96 |  | 
| 109 97 | 
             
            ```ruby
         | 
| 110 | 
            -
             | 
| 111 | 
            -
            order = Order.new( | 
| 112 | 
            -
            repository.load(order)
         | 
| 98 | 
            +
            stream_name = "Order$123"
         | 
| 99 | 
            +
            order = Order.new.load(stream_name)
         | 
| 113 100 | 
             
            ```
         | 
| 114 101 |  | 
| 115 102 | 
             
            Load gets all domain event stored for the aggregate in event store and apply them
         | 
| @@ -118,19 +105,19 @@ in order to given aggregate to rebuild aggregate's state. | |
| 118 105 | 
             
            #### Storing an aggregate root's changes in event store
         | 
| 119 106 |  | 
| 120 107 | 
             
            ```ruby
         | 
| 121 | 
            -
             | 
| 122 | 
            -
            order = Order.new( | 
| 123 | 
            -
            repository.load(order)
         | 
| 108 | 
            +
            stream_name = "Order$123"
         | 
| 109 | 
            +
            order = Order.new.load(stream_name)
         | 
| 124 110 | 
             
            order.submit
         | 
| 125 | 
            -
             | 
| 111 | 
            +
            order.store
         | 
| 126 112 | 
             
            ```
         | 
| 127 113 |  | 
| 128 114 | 
             
            Store gets all unpublished aggregate's domain events (created by executing a domain logic method like `submit`)
         | 
| 129 | 
            -
            and publish them in order of creation to event store.
         | 
| 115 | 
            +
            and publish them in order of creation to event store. If `stream_name` is not specified events will be stored
         | 
| 116 | 
            +
            in the same stream from which order has been loaded.
         | 
| 130 117 |  | 
| 131 118 | 
             
            #### Resources
         | 
| 132 119 |  | 
| 133 | 
            -
            There're already few  | 
| 120 | 
            +
            There're already few blog posts about building an event sourced applications with [rails_event_store](https://github.com/arkency/rails_event_store) and aggregate_root gems:
         | 
| 134 121 |  | 
| 135 122 | 
             
            * [Why use Event Sourcing](http://blog.arkency.com/2015/03/why-use-event-sourcing/)
         | 
| 136 123 | 
             
            * [The Event Store for Rails developers](http://blog.arkency.com/2015/04/the-event-store-for-rails-developers/)
         | 
    
        data/lib/aggregate_root.rb
    CHANGED
    
    | @@ -1,5 +1,43 @@ | |
| 1 | 
            +
            require 'active_support/inflector'
         | 
| 1 2 | 
             
            require 'aggregate_root/version'
         | 
| 2 | 
            -
            require 'aggregate_root/repository'
         | 
| 3 3 | 
             
            require 'aggregate_root/configuration'
         | 
| 4 | 
            -
            require 'aggregate_root/base'
         | 
| 5 4 | 
             
            require 'aggregate_root/default_apply_strategy'
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            module AggregateRoot
         | 
| 7 | 
            +
              def apply(event)
         | 
| 8 | 
            +
                apply_strategy.(self, event)
         | 
| 9 | 
            +
                unpublished_events << event
         | 
| 10 | 
            +
              end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
              def load(stream_name, event_store: default_event_store)
         | 
| 13 | 
            +
                @loaded_from_stream_name = stream_name
         | 
| 14 | 
            +
                events = event_store.read_stream_events_forward(stream_name)
         | 
| 15 | 
            +
                events.each do |event|
         | 
| 16 | 
            +
                  apply(event)
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
                @unpublished_events = nil
         | 
| 19 | 
            +
                self
         | 
| 20 | 
            +
              end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
              def store(stream_name = loaded_from_stream_name, event_store: default_event_store)
         | 
| 23 | 
            +
                unpublished_events.each do |event|
         | 
| 24 | 
            +
                  event_store.publish_event(event, stream_name: stream_name)
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
                @unpublished_events = nil
         | 
| 27 | 
            +
              end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
              private
         | 
| 30 | 
            +
              attr_reader :loaded_from_stream_name
         | 
| 31 | 
            +
             | 
| 32 | 
            +
              def unpublished_events
         | 
| 33 | 
            +
                @unpublished_events ||= []
         | 
| 34 | 
            +
              end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
              def apply_strategy
         | 
| 37 | 
            +
                DefaultApplyStrategy.new
         | 
| 38 | 
            +
              end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
              def default_event_store
         | 
| 41 | 
            +
                AggregateRoot.configuration.default_event_store
         | 
| 42 | 
            +
              end
         | 
| 43 | 
            +
            end
         | 
| @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            module AggregateRoot
         | 
| 2 2 | 
             
              class DefaultApplyStrategy
         | 
| 3 3 | 
             
                def call(aggregate, event)
         | 
| 4 | 
            -
                  event_name_processed = event.class. | 
| 4 | 
            +
                  event_name_processed = event.class.name.demodulize.underscore
         | 
| 5 5 | 
             
                  aggregate.method("apply_#{event_name_processed}").call(event)
         | 
| 6 6 | 
             
                end
         | 
| 7 7 | 
             
              end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: aggregate_root
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0. | 
| 4 | 
            +
              version: 0.4.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Arkency
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: exe
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2016-10- | 
| 11 | 
            +
            date: 2016-10-28 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: bundler
         | 
| @@ -140,10 +140,8 @@ files: | |
| 140 140 | 
             
            - Rakefile
         | 
| 141 141 | 
             
            - aggregate_root.gemspec
         | 
| 142 142 | 
             
            - lib/aggregate_root.rb
         | 
| 143 | 
            -
            - lib/aggregate_root/base.rb
         | 
| 144 143 | 
             
            - lib/aggregate_root/configuration.rb
         | 
| 145 144 | 
             
            - lib/aggregate_root/default_apply_strategy.rb
         | 
| 146 | 
            -
            - lib/aggregate_root/repository.rb
         | 
| 147 145 | 
             
            - lib/aggregate_root/version.rb
         | 
| 148 146 | 
             
            homepage: ''
         | 
| 149 147 | 
             
            licenses:
         | 
    
        data/lib/aggregate_root/base.rb
    DELETED
    
    | @@ -1,35 +0,0 @@ | |
| 1 | 
            -
            require 'active_support/inflector'
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            module AggregateRoot
         | 
| 4 | 
            -
              module Base
         | 
| 5 | 
            -
                attr_reader :id
         | 
| 6 | 
            -
             | 
| 7 | 
            -
                def apply(event)
         | 
| 8 | 
            -
                  apply_event(event)
         | 
| 9 | 
            -
                  unpublished_events << event
         | 
| 10 | 
            -
                end
         | 
| 11 | 
            -
             | 
| 12 | 
            -
                def apply_old_event(event)
         | 
| 13 | 
            -
                  apply_event(event)
         | 
| 14 | 
            -
                end
         | 
| 15 | 
            -
             | 
| 16 | 
            -
                def unpublished_events
         | 
| 17 | 
            -
                  @unpublished_events ||= []
         | 
| 18 | 
            -
                end
         | 
| 19 | 
            -
             | 
| 20 | 
            -
                private
         | 
| 21 | 
            -
                attr_writer :id
         | 
| 22 | 
            -
             | 
| 23 | 
            -
                def apply_strategy
         | 
| 24 | 
            -
                  DefaultApplyStrategy.new
         | 
| 25 | 
            -
                end
         | 
| 26 | 
            -
             | 
| 27 | 
            -
                def apply_event(event)
         | 
| 28 | 
            -
                  apply_strategy.(self, event)
         | 
| 29 | 
            -
                end
         | 
| 30 | 
            -
             | 
| 31 | 
            -
                def generate_uuid
         | 
| 32 | 
            -
                  SecureRandom.uuid
         | 
| 33 | 
            -
                end
         | 
| 34 | 
            -
              end
         | 
| 35 | 
            -
            end
         | 
| @@ -1,26 +0,0 @@ | |
| 1 | 
            -
            module AggregateRoot
         | 
| 2 | 
            -
              class Repository
         | 
| 3 | 
            -
                def initialize(event_store = default_event_store)
         | 
| 4 | 
            -
                  @event_store = event_store
         | 
| 5 | 
            -
                end
         | 
| 6 | 
            -
             | 
| 7 | 
            -
                def store(aggregate)
         | 
| 8 | 
            -
                  aggregate.unpublished_events.each do |event|
         | 
| 9 | 
            -
                    event_store.publish_event(event, stream_name: aggregate.id)
         | 
| 10 | 
            -
                  end
         | 
| 11 | 
            -
                end
         | 
| 12 | 
            -
             | 
| 13 | 
            -
                def load(aggregate)
         | 
| 14 | 
            -
                  events = event_store.read_stream_events_forward(aggregate.id)
         | 
| 15 | 
            -
                  events.each do |event|
         | 
| 16 | 
            -
                    aggregate.apply_old_event(event)
         | 
| 17 | 
            -
                  end
         | 
| 18 | 
            -
                end
         | 
| 19 | 
            -
             | 
| 20 | 
            -
                attr_accessor :event_store
         | 
| 21 | 
            -
             | 
| 22 | 
            -
                def default_event_store
         | 
| 23 | 
            -
                  AggregateRoot.configuration.default_event_store
         | 
| 24 | 
            -
                end
         | 
| 25 | 
            -
              end
         | 
| 26 | 
            -
            end
         |