eventsimple 1.2.0 → 1.2.2
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 +9 -0
- data/Gemfile.lock +5 -5
- data/README.md +0 -2
- data/app/controllers/eventsimple/entities_controller.rb +4 -0
- data/app/controllers/eventsimple/models_controller.rb +37 -2
- data/app/views/eventsimple/shared/_header.html.erb +12 -18
- data/app/views/layouts/eventsimple/application.html.erb +0 -6
- data/lib/eventsimple/entity.rb +5 -2
- data/lib/eventsimple/event.rb +1 -1
- data/lib/eventsimple/support/spec_helpers.rb +2 -0
- data/lib/eventsimple/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: 73a860de275fa7998ed8048ee53ac70ec2b7b5872456bd1c03422cb4218847cb
|
4
|
+
data.tar.gz: 0aee5f6d22f2630d1a513f3847441fb8e1f28399512f9046be161c65c4cb49f2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a92575ecbabbbf572beb4c61c7f46fff241e339b737d224ee93bf78b24df6dbedeab28a8fa7721d3a213b833e5f799b0a31e76234b41f7c903ea208ff04db2f9
|
7
|
+
data.tar.gz: 358feb4234563044b7609e46130913c161cdd2fa555cbfba7be4faea1e5e3bf3e26b83f546da72ab46142b1de5097976e13dfec56b44105077e80e33609e1f8e
|
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
|
+
## 1.2.2 - 2023-11-29
|
10
|
+
### Changed
|
11
|
+
- Add support for filtering events by aggregate model attributes.
|
12
|
+
|
13
|
+
## 1.2.1 - 2023-11-18
|
14
|
+
### Changed
|
15
|
+
- Allow timestamp data in events to override default timestamps update.
|
16
|
+
- This allows us to create temporal events for example in the case of snapshots.
|
17
|
+
|
9
18
|
## 1.2.0 - 2023-09-26
|
10
19
|
### Changed
|
11
20
|
- Fix issue where the reactor worker might not work correctly for models not inheriting from ApplicationRecord.
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
eventsimple (1.2.
|
4
|
+
eventsimple (1.2.2)
|
5
5
|
dry-struct (~> 1.6)
|
6
6
|
dry-types (~> 1.7)
|
7
7
|
pg (~> 1.4)
|
@@ -89,7 +89,7 @@ GEM
|
|
89
89
|
coderay (1.1.3)
|
90
90
|
concurrent-ruby (1.2.2)
|
91
91
|
crass (1.0.6)
|
92
|
-
date (3.3.
|
92
|
+
date (3.3.4)
|
93
93
|
diff-lcs (1.5.0)
|
94
94
|
dry-core (1.0.1)
|
95
95
|
concurrent-ruby (~> 1.0)
|
@@ -158,12 +158,12 @@ GEM
|
|
158
158
|
mini_mime (1.1.5)
|
159
159
|
minitest (5.20.0)
|
160
160
|
nenv (0.3.0)
|
161
|
-
net-imap (0.
|
161
|
+
net-imap (0.4.7)
|
162
162
|
date
|
163
163
|
net-protocol
|
164
164
|
net-pop (0.1.2)
|
165
165
|
net-protocol
|
166
|
-
net-protocol (0.2.
|
166
|
+
net-protocol (0.2.2)
|
167
167
|
timeout
|
168
168
|
net-smtp (0.4.0)
|
169
169
|
net-protocol
|
@@ -300,7 +300,7 @@ GEM
|
|
300
300
|
lint_roller (~> 1.0)
|
301
301
|
rubocop-rails (~> 2.20.2)
|
302
302
|
thor (1.2.2)
|
303
|
-
timeout (0.4.
|
303
|
+
timeout (0.4.1)
|
304
304
|
treetop (1.6.12)
|
305
305
|
polyglot (~> 0.3)
|
306
306
|
tzinfo (2.0.6)
|
data/README.md
CHANGED
@@ -8,6 +8,10 @@ module Eventsimple
|
|
8
8
|
@event_id = params[:e] || -1
|
9
9
|
@tab_id = (params[:t] == 'event') ? 'event' : 'entity'
|
10
10
|
|
11
|
+
filter_columns = @model_class._filter_attributes
|
12
|
+
params_filters = params.permit(filters: {})[:filters] || {}
|
13
|
+
@filters = filter_columns.to_h { |column| [column, params_filters[column]] }
|
14
|
+
|
11
15
|
primary_key = @model_class.event_class._aggregate_id
|
12
16
|
@entity = @model_class.find_by!(primary_key => @aggregate_id)
|
13
17
|
@entity_event_history = @entity.events.reverse
|
@@ -2,9 +2,44 @@ module Eventsimple
|
|
2
2
|
class ModelsController < ApplicationController
|
3
3
|
def show
|
4
4
|
@model_name = params[:name]
|
5
|
+
model_class = event_classes.find { |d| d.name == @model_name }
|
5
6
|
|
6
|
-
|
7
|
-
|
7
|
+
scope = apply_filter(model_class, model_class.event_class)
|
8
|
+
|
9
|
+
@latest_entities = scope.last(20).reverse
|
10
|
+
|
11
|
+
check_redirect_to_entity
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def apply_filter(model_class, model_event_class)
|
17
|
+
filter_columns = model_class._filter_attributes
|
18
|
+
|
19
|
+
params_filters = params.permit(filters: {})[:filters] || {}
|
20
|
+
@filters = filter_columns.to_h { |column| [column, params_filters[column]] }
|
21
|
+
|
22
|
+
return model_event_class unless @filters.any?
|
23
|
+
|
24
|
+
aggregate_class_symbol = model_event_class._aggregate_klass.model_name.element.to_sym
|
25
|
+
model_event_class = model_event_class.joins(aggregate_class_symbol)
|
26
|
+
@filters.each do |key, value|
|
27
|
+
next if value.blank?
|
28
|
+
key = model_event_class._aggregate_id if key == :aggregate_id
|
29
|
+
model_event_class = model_event_class.where({ aggregate_class_symbol => { key => value } })
|
30
|
+
end
|
31
|
+
|
32
|
+
model_event_class
|
33
|
+
end
|
34
|
+
|
35
|
+
def check_redirect_to_entity
|
36
|
+
return unless @latest_entities.any?
|
37
|
+
|
38
|
+
first_aggregate_id = @latest_entities.first.aggregate_id
|
39
|
+
|
40
|
+
return unless @latest_entities.all? { |entity| entity.aggregate_id == first_aggregate_id }
|
41
|
+
|
42
|
+
redirect_to model_entity_path(@model_name, first_aggregate_id, filters: @filters)
|
8
43
|
end
|
9
44
|
end
|
10
45
|
end
|
@@ -1,26 +1,20 @@
|
|
1
1
|
<!-- Header Search Start -->
|
2
2
|
<header class="container mb-4">
|
3
|
-
|
4
|
-
|
5
|
-
<
|
6
|
-
<
|
7
|
-
|
8
|
-
|
9
|
-
<option value="<%= model_path(klass) %>" <%= is_active %>><%= klass %></option>
|
10
|
-
<% end %>
|
11
|
-
</select>
|
12
|
-
</div>
|
13
|
-
|
14
|
-
<% if @model_name %>
|
15
|
-
<div class="col col-sm-7">
|
16
|
-
<%= form_with url: model_entity_path(@model_name, ''), id: 'model-search' do |f| %>
|
17
|
-
<%= f.search_field :event_id, class: 'form-control', placeholder: 'Canonical identifier', value: @aggregate_id, required: true, aria: { label: 'Entity canonical identifier' } %>
|
3
|
+
<% if @model_name %>
|
4
|
+
<%= form_with scope: :filters, url: model_path(@model_name), method: :get, id: 'model-filter' do |f| %>
|
5
|
+
<div class="row">
|
6
|
+
<label for="filters_keys[keys]" class="col-sm-2 col-form-label">Filter attribute</label>
|
7
|
+
<div class="form-group col-sm-3">
|
8
|
+
<%= select :filters_keys, :keys, @filters.keys, { selected: @filters.compact.keys&.first }, { class:"form-select", onchange: "document.getElementById('model-filter-value').name=`filters[${this.value}]`" } %>
|
18
9
|
</div>
|
19
|
-
<div class="
|
10
|
+
<div class="form-group col-sm-5">
|
11
|
+
<%= f.search_field @filters.compact.keys&.first || @filters.keys.first, id: 'model-filter-value', value: @filters.compact.values&.first, class:"form-control", placeholder: "Filter value" %>
|
12
|
+
</div>
|
13
|
+
<div class="form-group col-sm-2">
|
20
14
|
<%= f.submit 'Search', class: 'btn btn-primary' %>
|
21
|
-
|
15
|
+
</div>
|
22
16
|
</div>
|
23
17
|
<% end %>
|
24
|
-
|
18
|
+
<% end %>
|
25
19
|
</header>
|
26
20
|
<!-- Header Search End -->
|
@@ -62,12 +62,6 @@
|
|
62
62
|
query.set(param, value);
|
63
63
|
link.attr("href",window.location.pathname + '?' + query.toString());
|
64
64
|
});
|
65
|
-
|
66
|
-
$('#model-search').on('submit', (event) => {
|
67
|
-
event.preventDefault();
|
68
|
-
const form = $(event.currentTarget);
|
69
|
-
window.location = form.attr('action') + form.children('#event_id').val();
|
70
|
-
});
|
71
65
|
});
|
72
66
|
</script>
|
73
67
|
|
data/lib/eventsimple/entity.rb
CHANGED
@@ -2,7 +2,7 @@ module Eventsimple
|
|
2
2
|
module Entity
|
3
3
|
DEFAULT_IGNORE_PROPS = %w[id lock_version].freeze
|
4
4
|
|
5
|
-
def event_driven_by(event_klass, aggregate_id:)
|
5
|
+
def event_driven_by(event_klass, aggregate_id:, filter_attributes: [])
|
6
6
|
has_many :events, class_name: event_klass.name.to_s,
|
7
7
|
foreign_key: :aggregate_id,
|
8
8
|
primary_key: aggregate_id,
|
@@ -13,6 +13,9 @@ module Eventsimple
|
|
13
13
|
|
14
14
|
class_attribute :ignored_for_projection, default: []
|
15
15
|
|
16
|
+
class_attribute :_filter_attributes
|
17
|
+
self._filter_attributes = [aggregate_id] | Array.wrap(filter_attributes)
|
18
|
+
|
16
19
|
# disable automatic timestamp updates
|
17
20
|
self.record_timestamps = false
|
18
21
|
|
@@ -35,8 +38,8 @@ module Eventsimple
|
|
35
38
|
assign_attributes(self.class.column_defaults.except(*ignore_props))
|
36
39
|
|
37
40
|
event_history.each do |event|
|
38
|
-
event.apply(self)
|
39
41
|
event.apply_timestamps(self)
|
42
|
+
event.apply(self)
|
40
43
|
end
|
41
44
|
|
42
45
|
self
|
data/lib/eventsimple/event.rb
CHANGED
data/lib/eventsimple/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: eventsimple
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
4
|
+
version: 1.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Zulfiqar Ali
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-12-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dry-struct
|