esse-active_record 0.2.0 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 78a881c4b488d3a39ae25270bde1fc26444ba3369779257c385237933314e9c6
4
- data.tar.gz: 25e90b2d8820ab109a23812449b4fbd076081c843b3891ea1373977b48a85df6
3
+ metadata.gz: b48e48c6b27fee2e8612414bd9ba6730bbfd57ddc30b9f5ebadf5742c57d4be4
4
+ data.tar.gz: c1b74e88c8942aea5a72c58326c0051d57326ff6d6c61e80b723abd043dd74a1
5
5
  SHA512:
6
- metadata.gz: f9fba8e83ea38bae6667071fd9f416326af17227dc11061d41ae28305b35101d60babddd2ad8c02169876f673cf6cb712f68832f08d8b39dadbc448e2a0ae332
7
- data.tar.gz: 654fac3ac8f2eb1e52d977ee576a5565a0b3d9ce45ba239ab1fd0dd7a5c876ce42936f8270becfcbac6a7d12d82544bfcd7a7708f125bf76c9159ac9fc8ec6cd
6
+ metadata.gz: 46019ab0f4d79af084a062fe41de8d1341b9261f0cf3651c94bb3e290db71a0f1794350fed8f2ef58f8dbc98910c2854e7a15fd5027cce0f1fd057ccda734b34
7
+ data.tar.gz: e2c5861b580b09bf968d04a984ab3e6d94d27c89a2386a84397ceabf9860237be85ec135c79c387c3ad4559e4cbeb1462f863604de01f1a9c047143df0f5448a
data/.rubocop.yml CHANGED
@@ -31,9 +31,6 @@ RSpec/MessageSpies:
31
31
  RSpec/FilePath:
32
32
  Enabled: false
33
33
 
34
- RSpec/SpecFilePathFormat:
35
- Enabled: false
36
-
37
34
  Layout/SpaceInsideHashLiteralBraces:
38
35
  Enabled: false
39
36
 
@@ -49,3 +46,6 @@ Style/TrailingCommaInHashLiteral:
49
46
  Style/StringLiterals:
50
47
  Enabled: true
51
48
  EnforcedStyle: single_quotes
49
+
50
+ RSpec/MultipleMemoizedHelpers:
51
+ Max: 10
data/Gemfile CHANGED
@@ -2,8 +2,10 @@
2
2
 
3
3
  source 'https://rubygems.org'
4
4
 
5
- gem 'esse', '~> 0.2.4'
6
- gem 'sqlite3', '~> 1.3.6'
5
+ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
6
+
7
+ gem 'esse', '~> 0.3.0'
8
+ gem 'sqlite3', '~> 1.7.3'
7
9
  gem 'activerecord', '~> 5.2'
8
10
  gem 'esse-rspec', '~> 0.0.6'
9
11
  gem 'elasticsearch', '~> 7.17', '>= 7.17.10'
data/Gemfile.lock CHANGED
@@ -1,9 +1,9 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- esse-active_record (0.2.0)
4
+ esse-active_record (0.3.2)
5
5
  activerecord (>= 4.2, < 8)
6
- esse (>= 0.2.3)
6
+ esse (>= 0.3.0)
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
@@ -39,14 +39,12 @@ GEM
39
39
  elasticsearch-transport (7.17.10)
40
40
  faraday (>= 1, < 3)
41
41
  multi_json
42
- esse (0.2.6)
42
+ esse (0.3.0)
43
43
  multi_json
44
44
  thor (>= 0.19)
45
45
  esse-rspec (0.0.6)
46
46
  esse (>= 0.2.4)
47
47
  rspec (>= 3)
48
- factory_bot (6.2.0)
49
- activesupport (>= 5.0.0)
50
48
  faraday (2.8.1)
51
49
  base64
52
50
  faraday-net_http (>= 2.0, < 3.1)
@@ -59,6 +57,7 @@ GEM
59
57
  language_server-protocol (3.17.0.3)
60
58
  lint_roller (1.1.0)
61
59
  method_source (1.0.0)
60
+ mini_portile2 (2.8.7)
62
61
  minitest (5.21.2)
63
62
  multi_json (1.15.0)
64
63
  parallel (1.24.0)
@@ -109,7 +108,8 @@ GEM
109
108
  rubocop-capybara (~> 2.17)
110
109
  ruby-progressbar (1.13.0)
111
110
  ruby2_keywords (0.0.5)
112
- sqlite3 (1.3.13)
111
+ sqlite3 (1.7.3)
112
+ mini_portile2 (~> 2.8.0)
113
113
  standard (1.28.5)
114
114
  language_server-protocol (~> 3.17.0.2)
115
115
  lint_roller (~> 1.0)
@@ -122,7 +122,7 @@ GEM
122
122
  standard-performance (1.0.1)
123
123
  lint_roller (~> 1.0)
124
124
  rubocop-performance (~> 1.16.0)
125
- thor (1.3.0)
125
+ thor (1.3.1)
126
126
  thread_safe (0.3.6)
127
127
  tzinfo (1.2.11)
128
128
  thread_safe (~> 0.1)
@@ -142,17 +142,16 @@ DEPENDENCIES
142
142
  awesome_print
143
143
  dotenv
144
144
  elasticsearch (~> 7.17, >= 7.17.10)
145
- esse (~> 0.2.4)
145
+ esse (~> 0.3.0)
146
146
  esse-active_record!
147
147
  esse-rspec (~> 0.0.6)
148
- factory_bot
149
148
  pry
150
149
  rake
151
150
  rspec
152
151
  rubocop
153
152
  rubocop-performance
154
153
  rubocop-rspec
155
- sqlite3 (~> 1.3.6)
154
+ sqlite3 (~> 1.7.3)
156
155
  standard
157
156
  webmock
158
157
  yard
data/README.md CHANGED
@@ -154,7 +154,7 @@ end
154
154
 
155
155
  ### Indexing Callbacks
156
156
 
157
- The `index_callbacks` callback can be used to automaitcally index or delete documents after commit on create/update/destroy events.
157
+ The `index_callback` callback can be used to automaitcally index or delete documents after commit on create/update/destroy events.
158
158
 
159
159
  ```ruby
160
160
  class UsersIndex < Esse::Index
@@ -173,9 +173,9 @@ class User < ApplicationRecord
173
173
  # Using a index and repository as argument. Note that the index name is used instead of the
174
174
  # of the constant name. it's so because index and model depends on each other should result in
175
175
  # circular dependencies issues.
176
- index_callbacks 'users_index:user'
176
+ index_callback 'users_index:user'
177
177
  # Using a block to direct a different object to be indexed
178
- index_callbacks('organizations') { user.organization } # The `_index` suffix and repo name is optional on the index name
178
+ index_callback('organizations') { user.organization } # The `_index` suffix and repo name is optional on the index name
179
179
  end
180
180
  ```
181
181
 
@@ -194,7 +194,7 @@ or by some specific list of index or index's repository
194
194
  ```ruby
195
195
  Esse::ActiveRecord::Hooks.disable!(UsersIndex.repo)
196
196
  Esse::ActiveRecord::Hooks.enable!(UsersIndex.repo)
197
- Esse::ActiveRecord::Hooks.without_indexing(AccountsIndex UsersIndex.repo, ) do
197
+ Esse::ActiveRecord::Hooks.without_indexing(AccountsIndex, UsersIndex.repo) do
198
198
  10.times { User.create! }
199
199
  end
200
200
  ```
@@ -1,9 +1,9 @@
1
1
  PATH
2
2
  remote: ..
3
3
  specs:
4
- esse-active_record (0.2.0)
4
+ esse-active_record (0.3.2)
5
5
  activerecord (>= 4.2, < 8)
6
- esse (>= 0.2.3)
6
+ esse (>= 0.3.0)
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
@@ -39,7 +39,7 @@ GEM
39
39
  elasticsearch-transport (7.17.10)
40
40
  faraday (>= 1, < 3)
41
41
  multi_json
42
- esse (0.2.6)
42
+ esse (0.3.0)
43
43
  multi_json
44
44
  thor (>= 0.19)
45
45
  esse-rspec (0.0.6)
@@ -157,4 +157,4 @@ DEPENDENCIES
157
157
  yard
158
158
 
159
159
  BUNDLED WITH
160
- 2.3.21
160
+ 2.3.22
@@ -1,9 +1,9 @@
1
1
  PATH
2
2
  remote: ..
3
3
  specs:
4
- esse-active_record (0.2.0)
4
+ esse-active_record (0.3.2)
5
5
  activerecord (>= 4.2, < 8)
6
- esse (>= 0.2.3)
6
+ esse (>= 0.3.0)
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
@@ -37,16 +37,14 @@ GEM
37
37
  elasticsearch-transport (7.17.10)
38
38
  faraday (>= 1, < 3)
39
39
  multi_json
40
- esse (0.2.6)
40
+ esse (0.3.0)
41
41
  multi_json
42
42
  thor (>= 0.19)
43
43
  esse-rspec (0.0.6)
44
44
  esse (>= 0.2.4)
45
45
  rspec (>= 3)
46
- faraday (2.9.0)
47
- faraday-net_http (>= 2.0, < 3.2)
48
- faraday-net_http (3.1.0)
49
- net-http
46
+ faraday (2.0.0)
47
+ ruby2_keywords (>= 0.0.4)
50
48
  hashdiff (1.1.0)
51
49
  i18n (1.14.1)
52
50
  concurrent-ruby (~> 1.0)
@@ -54,10 +52,9 @@ GEM
54
52
  language_server-protocol (3.17.0.3)
55
53
  lint_roller (1.1.0)
56
54
  method_source (1.0.0)
55
+ mini_portile2 (2.8.7)
57
56
  minitest (5.21.2)
58
57
  multi_json (1.15.0)
59
- net-http (0.4.1)
60
- uri
61
58
  parallel (1.24.0)
62
59
  parser (3.3.0.5)
63
60
  ast (~> 2.4.1)
@@ -109,7 +106,9 @@ GEM
109
106
  rubocop-capybara (~> 2.17)
110
107
  rubocop-factory_bot (~> 2.22)
111
108
  ruby-progressbar (1.13.0)
112
- sqlite3 (1.7.0-x86_64-linux)
109
+ ruby2_keywords (0.0.5)
110
+ sqlite3 (1.7.3)
111
+ mini_portile2 (~> 2.8.0)
113
112
  standard (1.33.0)
114
113
  language_server-protocol (~> 3.17.0.2)
115
114
  lint_roller (~> 1.0)
@@ -126,7 +125,6 @@ GEM
126
125
  tzinfo (2.0.6)
127
126
  concurrent-ruby (~> 1.0)
128
127
  unicode-display_width (2.5.0)
129
- uri (0.13.0)
130
128
  webmock (3.19.1)
131
129
  addressable (>= 2.8.0)
132
130
  crack (>= 0.3.2)
@@ -1,9 +1,9 @@
1
1
  PATH
2
2
  remote: ..
3
3
  specs:
4
- esse-active_record (0.2.0)
4
+ esse-active_record (0.3.2)
5
5
  activerecord (>= 4.2, < 8)
6
- esse (>= 0.2.3)
6
+ esse (>= 0.3.0)
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
@@ -37,16 +37,14 @@ GEM
37
37
  elasticsearch-transport (7.17.10)
38
38
  faraday (>= 1, < 3)
39
39
  multi_json
40
- esse (0.2.6)
40
+ esse (0.3.0)
41
41
  multi_json
42
42
  thor (>= 0.19)
43
43
  esse-rspec (0.0.6)
44
44
  esse (>= 0.2.4)
45
45
  rspec (>= 3)
46
- faraday (2.9.0)
47
- faraday-net_http (>= 2.0, < 3.2)
48
- faraday-net_http (3.1.0)
49
- net-http
46
+ faraday (2.0.0)
47
+ ruby2_keywords (>= 0.0.4)
50
48
  hashdiff (1.1.0)
51
49
  i18n (1.14.1)
52
50
  concurrent-ruby (~> 1.0)
@@ -54,10 +52,9 @@ GEM
54
52
  language_server-protocol (3.17.0.3)
55
53
  lint_roller (1.1.0)
56
54
  method_source (1.0.0)
55
+ mini_portile2 (2.8.7)
57
56
  minitest (5.21.2)
58
57
  multi_json (1.15.0)
59
- net-http (0.4.1)
60
- uri
61
58
  parallel (1.24.0)
62
59
  parser (3.3.0.5)
63
60
  ast (~> 2.4.1)
@@ -109,7 +106,9 @@ GEM
109
106
  rubocop-capybara (~> 2.17)
110
107
  rubocop-factory_bot (~> 2.22)
111
108
  ruby-progressbar (1.13.0)
112
- sqlite3 (1.7.0-x86_64-linux)
109
+ ruby2_keywords (0.0.5)
110
+ sqlite3 (1.7.3)
111
+ mini_portile2 (~> 2.8.0)
113
112
  standard (1.33.0)
114
113
  language_server-protocol (~> 3.17.0.2)
115
114
  lint_roller (~> 1.0)
@@ -126,7 +125,6 @@ GEM
126
125
  tzinfo (2.0.6)
127
126
  concurrent-ruby (~> 1.0)
128
127
  unicode-display_width (2.5.0)
129
- uri (0.13.0)
130
128
  webmock (3.19.1)
131
129
  addressable (>= 2.8.0)
132
130
  crack (>= 0.3.2)
@@ -1,9 +1,9 @@
1
1
  PATH
2
2
  remote: ..
3
3
  specs:
4
- esse-active_record (0.2.0)
4
+ esse-active_record (0.3.2)
5
5
  activerecord (>= 4.2, < 8)
6
- esse (>= 0.2.3)
6
+ esse (>= 0.3.0)
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
@@ -37,16 +37,14 @@ GEM
37
37
  elasticsearch-transport (7.17.10)
38
38
  faraday (>= 1, < 3)
39
39
  multi_json
40
- esse (0.2.6)
40
+ esse (0.3.0)
41
41
  multi_json
42
42
  thor (>= 0.19)
43
43
  esse-rspec (0.0.6)
44
44
  esse (>= 0.2.4)
45
45
  rspec (>= 3)
46
- faraday (2.9.0)
47
- faraday-net_http (>= 2.0, < 3.2)
48
- faraday-net_http (3.1.0)
49
- net-http
46
+ faraday (2.0.0)
47
+ ruby2_keywords (>= 0.0.4)
50
48
  hashdiff (1.1.0)
51
49
  i18n (1.14.1)
52
50
  concurrent-ruby (~> 1.0)
@@ -54,10 +52,9 @@ GEM
54
52
  language_server-protocol (3.17.0.3)
55
53
  lint_roller (1.1.0)
56
54
  method_source (1.0.0)
55
+ mini_portile2 (2.8.7)
57
56
  minitest (5.21.2)
58
57
  multi_json (1.15.0)
59
- net-http (0.4.1)
60
- uri
61
58
  parallel (1.24.0)
62
59
  parser (3.3.0.5)
63
60
  ast (~> 2.4.1)
@@ -109,7 +106,9 @@ GEM
109
106
  rubocop-capybara (~> 2.17)
110
107
  rubocop-factory_bot (~> 2.22)
111
108
  ruby-progressbar (1.13.0)
112
- sqlite3 (1.7.0-x86_64-linux)
109
+ ruby2_keywords (0.0.5)
110
+ sqlite3 (1.7.3)
111
+ mini_portile2 (~> 2.8.0)
113
112
  standard (1.33.0)
114
113
  language_server-protocol (~> 3.17.0.2)
115
114
  lint_roller (~> 1.0)
@@ -126,7 +125,6 @@ GEM
126
125
  tzinfo (2.0.6)
127
126
  concurrent-ruby (~> 1.0)
128
127
  unicode-display_width (2.5.0)
129
- uri (0.13.0)
130
128
  webmock (3.19.1)
131
129
  addressable (>= 2.8.0)
132
130
  crack (>= 0.3.2)
@@ -1,9 +1,9 @@
1
1
  PATH
2
2
  remote: ..
3
3
  specs:
4
- esse-active_record (0.2.0)
4
+ esse-active_record (0.3.2)
5
5
  activerecord (>= 4.2, < 8)
6
- esse (>= 0.2.3)
6
+ esse (>= 0.3.0)
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
@@ -47,16 +47,14 @@ GEM
47
47
  elasticsearch-transport (7.17.10)
48
48
  faraday (>= 1, < 3)
49
49
  multi_json
50
- esse (0.2.6)
50
+ esse (0.3.0)
51
51
  multi_json
52
52
  thor (>= 0.19)
53
53
  esse-rspec (0.0.6)
54
54
  esse (>= 0.2.4)
55
55
  rspec (>= 3)
56
- faraday (2.9.0)
57
- faraday-net_http (>= 2.0, < 3.2)
58
- faraday-net_http (3.1.0)
59
- net-http
56
+ faraday (2.0.0)
57
+ ruby2_keywords (>= 0.0.4)
60
58
  hashdiff (1.1.0)
61
59
  i18n (1.14.1)
62
60
  concurrent-ruby (~> 1.0)
@@ -64,11 +62,10 @@ GEM
64
62
  language_server-protocol (3.17.0.3)
65
63
  lint_roller (1.1.0)
66
64
  method_source (1.0.0)
65
+ mini_portile2 (2.8.7)
67
66
  minitest (5.21.2)
68
67
  multi_json (1.15.0)
69
68
  mutex_m (0.2.0)
70
- net-http (0.4.1)
71
- uri
72
69
  parallel (1.24.0)
73
70
  parser (3.3.0.5)
74
71
  ast (~> 2.4.1)
@@ -121,7 +118,8 @@ GEM
121
118
  rubocop-factory_bot (~> 2.22)
122
119
  ruby-progressbar (1.13.0)
123
120
  ruby2_keywords (0.0.5)
124
- sqlite3 (1.7.0-x86_64-linux)
121
+ sqlite3 (1.7.3)
122
+ mini_portile2 (~> 2.8.0)
125
123
  standard (1.33.0)
126
124
  language_server-protocol (~> 3.17.0.2)
127
125
  lint_roller (~> 1.0)
@@ -139,7 +137,6 @@ GEM
139
137
  tzinfo (2.0.6)
140
138
  concurrent-ruby (~> 1.0)
141
139
  unicode-display_width (2.5.0)
142
- uri (0.13.0)
143
140
  webmock (3.19.1)
144
141
  addressable (>= 2.8.0)
145
142
  crack (>= 0.3.2)
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Esse::ActiveRecord
4
+ module Callbacks
5
+ class IndexingOnCreate < Callback
6
+ def call(model)
7
+ record = block_result || model
8
+ document = repo.serialize(record)
9
+ repo.index.index(document, **options) if document
10
+ true
11
+ end
12
+ end
13
+
14
+ register_callback(:indexing, :create, IndexingOnCreate)
15
+ end
16
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Esse::ActiveRecord
4
+ module Callbacks
5
+ class IndexingOnDestroy < Callback
6
+ def call(model)
7
+ record = block_result || model
8
+ document = repo.serialize(record)
9
+ repo.index.delete(document, **options) if document
10
+ true
11
+ rescue Esse::Transport::NotFoundError
12
+ true
13
+ end
14
+ end
15
+
16
+ register_callback(:indexing, :destroy, IndexingOnDestroy)
17
+ end
18
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Esse::ActiveRecord
4
+ module Callbacks
5
+ class IndexingOnUpdate < Callback
6
+ attr_reader :update_with
7
+
8
+ def initialize(with: :index, **kwargs, &block)
9
+ @update_with = with
10
+ super(**kwargs, &block)
11
+ end
12
+
13
+ def call(model)
14
+ record = block_result || model
15
+
16
+ document = repo.serialize(record)
17
+ return true unless document
18
+
19
+ update_document(document)
20
+ return true unless document.routing
21
+
22
+ prev_record = model.class.new(model.attributes.merge(model.previous_changes.transform_values(&:first))).tap(&:readonly!)
23
+ prev_document = repo.serialize(prev_record)
24
+
25
+ return true unless prev_document
26
+ return true if [prev_document.id, prev_document.routing].include?(nil)
27
+ return true if prev_document.routing == document.routing
28
+ return true if prev_document.id != document.id
29
+
30
+ begin
31
+ repo.index.delete(prev_document, **options)
32
+ rescue Esse::Transport::NotFoundError
33
+ end
34
+
35
+ true
36
+ end
37
+
38
+ protected
39
+
40
+ def update_document(document)
41
+ if update_with == :update
42
+ begin
43
+ repo.index.update(document, **options)
44
+ rescue Esse::Transport::NotFoundError
45
+ repo.index.index(document, **options)
46
+ end
47
+ else
48
+ repo.index.index(document, **options)
49
+ end
50
+ end
51
+ end
52
+
53
+ register_callback(:indexing, :update, IndexingOnUpdate)
54
+ end
55
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Esse::ActiveRecord
4
+ module Callbacks
5
+ class UpdateLazyAttribute < Callback
6
+ attr_reader :attribute_name
7
+
8
+ def initialize(attribute_name:, **kwargs, &block)
9
+ @attribute_name = attribute_name
10
+ super(**kwargs, &block)
11
+ end
12
+
13
+ def call(model)
14
+ related_ids = Array(block_result || model.id)
15
+ return true if related_ids.empty?
16
+
17
+ repo.update_documents_attribute(attribute_name, *related_ids, **options)
18
+
19
+ true
20
+ end
21
+ end
22
+
23
+ register_callback(:update_lazy_attribute, :create, UpdateLazyAttribute)
24
+ register_callback(:update_lazy_attribute, :update, UpdateLazyAttribute)
25
+ register_callback(:update_lazy_attribute, :destroy, UpdateLazyAttribute)
26
+ end
27
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Esse
4
+ module ActiveRecord
5
+ class Callback
6
+ attr_reader :repo, :options, :block_result
7
+
8
+ def initialize(repo:, block_result: nil, **kwargs)
9
+ @repo = repo
10
+ @options = kwargs
11
+ @block_result = block_result
12
+ end
13
+
14
+ def call(model)
15
+ raise NotImplementedError, 'You must implement #call method'
16
+ end
17
+ end
18
+
19
+ module Callbacks
20
+ class << self
21
+ def to_h
22
+ @callbacks || {}.freeze
23
+ end
24
+
25
+ def register_callback(identifier, operation, callback_class)
26
+ unless callback_class < Esse::ActiveRecord::Callback
27
+ raise ArgumentError, 'callback_class must be a subclass of Esse::ActiveRecord::Callback'
28
+ end
29
+
30
+ key = :"#{identifier}_on_#{operation}"
31
+
32
+ @callbacks = @callbacks ? @callbacks.dup : {}
33
+ if @callbacks.key?(key)
34
+ raise ArgumentError, "callback #{identifier} for #{operation} operation already registered"
35
+ end
36
+
37
+ @callbacks[key] = callback_class
38
+ ensure
39
+ @callbacks&.freeze
40
+ end
41
+
42
+ def registered?(identifier, operation)
43
+ return false unless @callbacks
44
+
45
+ @callbacks.key?(:"#{identifier}_on_#{operation}")
46
+ end
47
+
48
+ def fetch!(identifier, operation)
49
+ key = :"#{identifier}_on_#{operation}"
50
+ if registered?(identifier, operation)
51
+ [key, @callbacks[key]]
52
+ else
53
+ raise ArgumentError, "callback #{identifier} for #{operation} operation not registered"
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+
61
+ require_relative 'callbacks/indexing_on_create'
62
+ require_relative 'callbacks/indexing_on_update'
63
+ require_relative 'callbacks/indexing_on_destroy'
64
+ require_relative 'callbacks/update_lazy_attribute'
@@ -82,7 +82,7 @@ module Esse
82
82
  def ensure_registered_model_class!(model_class)
83
83
  return if registered_model_class?(model_class)
84
84
 
85
- raise ArgumentError, "Model class #{model_class} is not registered. The model should inherit from Esse::ActiveRecord::Model and have a `index_callbacks' callback defined"
85
+ raise ArgumentError, "Model class #{model_class} is not registered. The model should inherit from Esse::ActiveRecord::Model and have a `index_callback' callback defined"
86
86
  end
87
87
 
88
88
  # Check if the given model is enabled for indexing. If no repository is specified, all repositories will be checked.
@@ -147,7 +147,7 @@ module Esse
147
147
  # Returns a list of all repositories for the given model
148
148
  # @return [Array<Symbol>]
149
149
  def model_repos(model_class)
150
- expand_index_repos(*model_class.esse_index_repos.keys)
150
+ expand_index_repos(*model_class.esse_callbacks.keys)
151
151
  end
152
152
 
153
153
  # Returns a list of all repositories for the given model
@@ -5,13 +5,40 @@ module Esse
5
5
  module Model
6
6
  extend ActiveSupport::Concern
7
7
 
8
- def self.inherited(subclass)
9
- super
10
- subclass.esse_index_repos = esse_index_repos.dup
11
- end
12
-
13
8
  module ClassMethods
14
- attr_reader :esse_index_repos
9
+ extend Esse::Deprecations::Deprecate
10
+
11
+ def esse_callbacks
12
+ @esse_callbacks ||= {}.freeze
13
+ end
14
+
15
+ def esse_callback(index_repo_name, operation_name, on: %i[create update destroy], **options, &block)
16
+ @esse_callbacks = esse_callbacks.dup
17
+ if_enabled = -> { Esse::ActiveRecord::Hooks.enabled?(index_repo_name) && Esse::ActiveRecord::Hooks.enabled_for_model?(self.class, index_repo_name) }
18
+
19
+ Array(on).each do |event|
20
+ identifier, klass = Esse::ActiveRecord::Callbacks.fetch!(operation_name, event)
21
+
22
+ if @esse_callbacks.dig(index_repo_name, identifier)
23
+ raise ArgumentError, format('index repository %<name>p already registered %<op>s operation', name: index_repo_name, op: operation_name)
24
+ end
25
+
26
+ @esse_callbacks[index_repo_name] = @esse_callbacks[index_repo_name]&.dup || {}
27
+ @esse_callbacks[index_repo_name][identifier] = [klass, options, block]
28
+
29
+ after_commit(on: event, if: if_enabled) do
30
+ klass, options, block = self.class.esse_callbacks.fetch(index_repo_name).fetch(identifier)
31
+ options[:repo] = Esse::ActiveRecord::Hooks.resolve_index_repository(index_repo_name)
32
+ options[:block_result] = instance_exec(&block) if block.respond_to?(:call)
33
+ instance = klass.new(**options)
34
+ instance.call(self)
35
+ end
36
+ end
37
+
38
+ Esse::ActiveRecord::Hooks.register_model(self)
39
+ ensure
40
+ @esse_callbacks&.each_value { |v| v.freeze }&.freeze
41
+ end
15
42
 
16
43
  # Define callback for create/update/delete elasticsearch index document after model commit.
17
44
  #
@@ -21,49 +48,25 @@ module Esse
21
48
  # For namespace, use `/` as the separator.
22
49
  # @raise [ArgumentError] when the repo and events are already registered
23
50
  # @raise [ArgumentError] when the specified index have multiple repos
24
- def index_callbacks(index_repo_name, on: %i[create update destroy], **options, &block)
25
- @esse_index_repos ||= {}
26
-
27
- operation_name = :index
28
- if esse_index_repos.dig(index_repo_name, operation_name)
29
- raise ArgumentError, format('index repository %<name>p already registered %<op>s operation', name: index_repo_name, op: operation_name)
30
- end
31
-
32
- esse_index_repos[index_repo_name] ||= {}
33
- esse_index_repos[index_repo_name][operation_name] = {
34
- record: block || -> { self },
35
- options: options,
36
- }
37
-
38
- Esse::ActiveRecord::Hooks.register_model(self)
39
-
40
- if_enabled = -> { Esse::ActiveRecord::Hooks.enabled?(index_repo_name) && Esse::ActiveRecord::Hooks.enabled_for_model?(self.class, index_repo_name) }
41
- (on & %i[create update]).each do |event|
42
- after_commit(on: event, if: if_enabled) do
43
- opts = self.class.esse_index_repos.fetch(index_repo_name).fetch(operation_name)
44
- record = opts.fetch(:record)
45
- record = instance_exec(&record) if record.respond_to?(:call)
46
- repo = Esse::ActiveRecord::Hooks.resolve_index_repository(index_repo_name)
47
- document = repo.serialize(record)
48
- repo.index.index(document, **opts[:options]) if document
49
- true
50
- end
51
- end
52
- (on & %i[destroy]).each do |event|
53
- after_commit(on: event, if: if_enabled) do
54
- opts = self.class.esse_index_repos.fetch(index_repo_name).fetch(operation_name)
55
- record = opts.fetch(:record)
56
- record = instance_exec(&record) if record.respond_to?(:call)
57
- repo = Esse::ActiveRecord::Hooks.resolve_index_repository(index_repo_name)
58
- document = repo.serialize(record)
59
- repo.index.delete(document, **opts[:options]) if document
60
- true
61
- rescue Esse::Transport::NotFoundError
62
- true
51
+ def index_callback(index_repo_name, on: %i[create update destroy], with: nil, **options, &block)
52
+ if with
53
+ Array(on).each do |event|
54
+ if on == :update
55
+ esse_callback(index_repo_name, :indexing, on: event, with: with, **options, &block)
56
+ else
57
+ esse_callback(index_repo_name, :indexing, on: event, **options, &block)
58
+ end
63
59
  end
60
+ else
61
+ esse_callback(index_repo_name, :indexing, on: on, **options, &block)
64
62
  end
65
63
  end
66
64
 
65
+ def update_lazy_attribute_callback(index_repo_name, attribute_name, on: %i[create update destroy], **options, &block)
66
+ options[:attribute_name] = attribute_name
67
+ esse_callback(index_repo_name, :update_lazy_attribute, on: on, **options, &block)
68
+ end
69
+
67
70
  # Disable indexing for the block execution on model level
68
71
  # Example:
69
72
  # User.without_indexing { }
@@ -73,6 +76,16 @@ module Esse
73
76
  yield
74
77
  end
75
78
  end
79
+
80
+ def index_callbacks(*args, **options, &block)
81
+ index_callback(*args, **options, &block)
82
+ end
83
+ deprecate :index_callbacks, :index_callback, 2024, 12
84
+
85
+ def esse_index_repos
86
+ esse_callbacks
87
+ end
88
+ deprecate :esse_index_repos, :esse_callbacks, 2024, 12
76
89
  end
77
90
  end
78
91
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Esse
4
4
  module ActiveRecord
5
- VERSION = '0.2.0'
5
+ VERSION = '0.3.2'
6
6
  end
7
7
  end
@@ -3,6 +3,7 @@
3
3
  require 'esse'
4
4
  require 'active_record'
5
5
  require_relative 'active_record/version'
6
+ require_relative 'active_record/callbacks'
6
7
  require_relative 'active_record/model'
7
8
  require_relative 'active_record/hooks'
8
9
  require_relative 'active_record/collection'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: esse-active_record
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marcos G. Zimmermann
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-01-24 00:00:00.000000000 Z
11
+ date: 2024-07-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: esse
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 0.2.3
19
+ version: 0.3.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 0.2.3
26
+ version: 0.3.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: activerecord
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -222,6 +222,11 @@ files:
222
222
  - ci/Gemfile.rails-7.1
223
223
  - ci/Gemfile.rails-7.1.lock
224
224
  - lib/esse/active_record.rb
225
+ - lib/esse/active_record/callbacks.rb
226
+ - lib/esse/active_record/callbacks/indexing_on_create.rb
227
+ - lib/esse/active_record/callbacks/indexing_on_destroy.rb
228
+ - lib/esse/active_record/callbacks/indexing_on_update.rb
229
+ - lib/esse/active_record/callbacks/update_lazy_attribute.rb
225
230
  - lib/esse/active_record/collection.rb
226
231
  - lib/esse/active_record/hooks.rb
227
232
  - lib/esse/active_record/model.rb
@@ -250,7 +255,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
250
255
  - !ruby/object:Gem::Version
251
256
  version: '0'
252
257
  requirements: []
253
- rubygems_version: 3.2.32
258
+ rubygems_version: 3.1.6
254
259
  signing_key:
255
260
  specification_version: 4
256
261
  summary: ActiveRecord extensions for Esse