From a9e871aca6446bbdd285cf0c1bbae50413fc3e7a Mon Sep 17 00:00:00 2001 From: "Marcos G. Zimmermann" Date: Mon, 29 Jul 2024 15:46:07 -0300 Subject: [PATCH] feat: async index (#5) * feat: async index * feat: esse-async_indexing use the #each_batch_ids collection method * fix: exclude :eager_load data from each_batch_ids * feat: do not call api when document is set to ignore * chore: update structure of callback naming * chore: update_lazy_attribute_callback by attribute * feat: add count and size to collection * bump version * update ci gemfile dependencies * The `RSpec/FilePath` cop has been split into `RSpec/SpecFilePathFormat` and `RSpec/SpecFilePathSuffix`. * Call super without arguments and parentheses when the signature is identical --- .rubocop.yml | 3 - Gemfile | 2 +- Gemfile.lock | 6 +- ci/Gemfile.rails-5.2.lock | 113 ++++++++------- ci/Gemfile.rails-6.0.lock | 133 ++++++++--------- ci/Gemfile.rails-6.1.lock | 133 ++++++++--------- ci/Gemfile.rails-7.0.lock | 133 ++++++++--------- ci/Gemfile.rails-7.1.lock | 134 +++++++++--------- lib/esse/active_record/callbacks.rb | 7 +- .../callbacks/indexing_on_create.rb | 2 +- .../callbacks/indexing_on_destroy.rb | 2 +- .../callbacks/indexing_on_update.rb | 2 + lib/esse/active_record/collection.rb | 11 ++ lib/esse/active_record/model.rb | 7 +- lib/esse/active_record/version.rb | 2 +- lib/esse/plugins/active_record.rb | 2 +- spec/esse/active_record/callbacks_spec.rb | 2 +- spec/esse/active_record/collection_spec.rb | 65 +++++++++ .../active_record/model/esse_callback_spec.rb | 10 +- .../update_lazy_attribute_callback_spec.rb | 27 +++- 20 files changed, 449 insertions(+), 347 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 9d09794..9ff059d 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -28,9 +28,6 @@ RSpec/ExampleLength: RSpec/MessageSpies: Enabled: false -RSpec/FilePath: - Enabled: false - Layout/SpaceInsideHashLiteralBraces: Enabled: false diff --git a/Gemfile b/Gemfile index 1a0887d..ccb8b58 100644 --- a/Gemfile +++ b/Gemfile @@ -4,7 +4,7 @@ source 'https://rubygems.org' git_source(:github) { |repo_name| "https://github.com/#{repo_name}" } -gem 'esse', '~> 0.3.1' +gem 'esse', '~> 0.3.4' gem 'sqlite3', '~> 1.7.3' gem 'activerecord', '~> 5.2' gem 'esse-rspec', '~> 0.0.6' diff --git a/Gemfile.lock b/Gemfile.lock index b28db9f..181a27e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - esse-active_record (0.3.4) + esse-active_record (0.3.5) activerecord (>= 4.2, < 8) esse (>= 0.3.0) @@ -39,7 +39,7 @@ GEM elasticsearch-transport (7.17.10) faraday (>= 1, < 3) multi_json - esse (0.3.1) + esse (0.3.4) multi_json thor (>= 0.19) esse-rspec (0.0.6) @@ -142,7 +142,7 @@ DEPENDENCIES awesome_print dotenv elasticsearch (~> 7.17, >= 7.17.10) - esse (~> 0.3.1) + esse (~> 0.3.4) esse-active_record! esse-rspec (~> 0.0.6) pry diff --git a/ci/Gemfile.rails-5.2.lock b/ci/Gemfile.rails-5.2.lock index 9ea0ac8..ed904df 100644 --- a/ci/Gemfile.rails-5.2.lock +++ b/ci/Gemfile.rails-5.2.lock @@ -1,7 +1,7 @@ PATH remote: .. specs: - esse-active_record (0.3.4) + esse-active_record (0.3.5) activerecord (>= 4.2, < 8) esse (>= 0.3.0) @@ -19,27 +19,30 @@ GEM i18n (>= 0.7, < 2) minitest (~> 5.1) tzinfo (~> 1.1) - addressable (2.8.6) - public_suffix (>= 2.0.2, < 6.0) + addressable (2.8.7) + public_suffix (>= 2.0.2, < 7.0) arel (9.0.0) ast (2.4.2) awesome_print (1.9.2) base64 (0.2.0) + bigdecimal (3.1.8) coderay (1.1.3) - concurrent-ruby (1.2.3) - crack (0.4.5) + concurrent-ruby (1.3.3) + crack (1.0.0) + bigdecimal rexml - diff-lcs (1.5.0) + diff-lcs (1.5.1) dotenv (2.8.1) - elasticsearch (7.17.10) - elasticsearch-api (= 7.17.10) - elasticsearch-transport (= 7.17.10) - elasticsearch-api (7.17.10) + elasticsearch (7.17.11) + elasticsearch-api (= 7.17.11) + elasticsearch-transport (= 7.17.11) + elasticsearch-api (7.17.11) multi_json - elasticsearch-transport (7.17.10) + elasticsearch-transport (7.17.11) + base64 faraday (>= 1, < 3) multi_json - esse (0.3.0) + esse (0.3.4) multi_json thor (>= 0.19) esse-rspec (0.0.6) @@ -51,89 +54,85 @@ GEM ruby2_keywords (>= 0.0.4) faraday-net_http (3.0.2) hashdiff (1.1.0) - i18n (1.14.1) + i18n (1.14.5) concurrent-ruby (~> 1.0) - json (2.7.1) + json (2.7.2) language_server-protocol (3.17.0.3) lint_roller (1.1.0) - method_source (1.0.0) - minitest (5.21.2) + method_source (1.1.0) + minitest (5.24.1) multi_json (1.15.0) - parallel (1.24.0) - parser (3.3.0.5) + parallel (1.25.1) + parser (3.3.4.0) ast (~> 2.4.1) racc pry (0.14.2) coderay (~> 1.1) method_source (~> 1.0) - public_suffix (5.0.4) - racc (1.7.3) + public_suffix (5.1.1) + racc (1.8.0) rainbow (3.1.1) - rake (13.1.0) - regexp_parser (2.9.0) - rexml (3.2.6) - rspec (3.12.0) - rspec-core (~> 3.12.0) - rspec-expectations (~> 3.12.0) - rspec-mocks (~> 3.12.0) - rspec-core (3.12.2) - rspec-support (~> 3.12.0) - rspec-expectations (3.12.3) + rake (13.2.1) + regexp_parser (2.9.2) + rexml (3.3.2) + strscan + rspec (3.13.0) + rspec-core (~> 3.13.0) + rspec-expectations (~> 3.13.0) + rspec-mocks (~> 3.13.0) + rspec-core (3.13.0) + rspec-support (~> 3.13.0) + rspec-expectations (3.13.1) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.12.0) - rspec-mocks (3.12.6) + rspec-support (~> 3.13.0) + rspec-mocks (3.13.1) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.12.0) - rspec-support (3.12.1) - rubocop (1.59.0) + rspec-support (~> 3.13.0) + rspec-support (3.13.1) + rubocop (1.64.1) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) - parser (>= 3.2.2.4) + parser (>= 3.3.0.2) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 1.8, < 3.0) rexml (>= 3.2.5, < 4.0) - rubocop-ast (>= 1.30.0, < 2.0) + rubocop-ast (>= 1.31.1, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 3.0) - rubocop-ast (1.30.0) - parser (>= 3.2.1.0) - rubocop-capybara (2.20.0) - rubocop (~> 1.41) - rubocop-factory_bot (2.25.1) - rubocop (~> 1.41) - rubocop-performance (1.20.2) + rubocop-ast (1.31.3) + parser (>= 3.3.1.0) + rubocop-performance (1.21.1) rubocop (>= 1.48.1, < 2.0) - rubocop-ast (>= 1.30.0, < 2.0) - rubocop-rspec (2.26.1) - rubocop (~> 1.40) - rubocop-capybara (~> 2.17) - rubocop-factory_bot (~> 2.22) + rubocop-ast (>= 1.31.1, < 2.0) + rubocop-rspec (3.0.3) + rubocop (~> 1.61) ruby-progressbar (1.13.0) ruby2_keywords (0.0.5) sqlite3 (1.3.13) - standard (1.33.0) + standard (1.37.0) language_server-protocol (~> 3.17.0.2) lint_roller (~> 1.0) - rubocop (~> 1.59.0) + rubocop (~> 1.64.0) standard-custom (~> 1.0.0) - standard-performance (~> 1.3) + standard-performance (~> 1.4) standard-custom (1.0.2) lint_roller (~> 1.0) rubocop (~> 1.50) - standard-performance (1.3.1) + standard-performance (1.4.0) lint_roller (~> 1.1) - rubocop-performance (~> 1.20.2) - thor (1.3.0) + rubocop-performance (~> 1.21.0) + strscan (3.1.0) + thor (1.3.1) thread_safe (0.3.6) tzinfo (1.2.11) thread_safe (~> 0.1) unicode-display_width (2.5.0) - webmock (3.19.1) + webmock (3.23.1) addressable (>= 2.8.0) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) - yard (0.9.34) + yard (0.9.36) PLATFORMS x86_64-linux diff --git a/ci/Gemfile.rails-6.0.lock b/ci/Gemfile.rails-6.0.lock index 6d1bf5a..474f759 100644 --- a/ci/Gemfile.rails-6.0.lock +++ b/ci/Gemfile.rails-6.0.lock @@ -1,136 +1,139 @@ PATH remote: .. specs: - esse-active_record (0.3.4) + esse-active_record (0.3.5) activerecord (>= 4.2, < 8) esse (>= 0.3.0) GEM remote: https://rubygems.org/ specs: - activemodel (6.1.7.6) - activesupport (= 6.1.7.6) - activerecord (6.1.7.6) - activemodel (= 6.1.7.6) - activesupport (= 6.1.7.6) - activesupport (6.1.7.6) + activemodel (6.1.7.8) + activesupport (= 6.1.7.8) + activerecord (6.1.7.8) + activemodel (= 6.1.7.8) + activesupport (= 6.1.7.8) + activesupport (6.1.7.8) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 1.6, < 2) minitest (>= 5.1) tzinfo (~> 2.0) zeitwerk (~> 2.3) - addressable (2.8.6) - public_suffix (>= 2.0.2, < 6.0) + addressable (2.8.7) + public_suffix (>= 2.0.2, < 7.0) ast (2.4.2) awesome_print (1.9.2) + base64 (0.2.0) + bigdecimal (3.1.8) coderay (1.1.3) - concurrent-ruby (1.2.3) - crack (0.4.5) + concurrent-ruby (1.3.3) + crack (1.0.0) + bigdecimal rexml - diff-lcs (1.5.0) + diff-lcs (1.5.1) dotenv (2.8.1) - elasticsearch (7.17.10) - elasticsearch-api (= 7.17.10) - elasticsearch-transport (= 7.17.10) - elasticsearch-api (7.17.10) + elasticsearch (7.17.11) + elasticsearch-api (= 7.17.11) + elasticsearch-transport (= 7.17.11) + elasticsearch-api (7.17.11) multi_json - elasticsearch-transport (7.17.10) + elasticsearch-transport (7.17.11) + base64 faraday (>= 1, < 3) multi_json - esse (0.3.0) + esse (0.3.4) multi_json thor (>= 0.19) esse-rspec (0.0.6) esse (>= 0.2.4) rspec (>= 3) - faraday (2.0.0) + faraday (2.8.1) + base64 + faraday-net_http (>= 2.0, < 3.1) ruby2_keywords (>= 0.0.4) + faraday-net_http (3.0.2) hashdiff (1.1.0) - i18n (1.14.1) + i18n (1.14.5) concurrent-ruby (~> 1.0) - json (2.7.1) + json (2.7.2) language_server-protocol (3.17.0.3) lint_roller (1.1.0) - method_source (1.0.0) + method_source (1.1.0) mini_portile2 (2.8.7) - minitest (5.21.2) + minitest (5.24.1) multi_json (1.15.0) - parallel (1.24.0) - parser (3.3.0.5) + parallel (1.25.1) + parser (3.3.4.0) ast (~> 2.4.1) racc pry (0.14.2) coderay (~> 1.1) method_source (~> 1.0) - public_suffix (5.0.4) - racc (1.7.3) + public_suffix (5.1.1) + racc (1.8.0) rainbow (3.1.1) - rake (13.1.0) - regexp_parser (2.9.0) - rexml (3.2.6) - rspec (3.12.0) - rspec-core (~> 3.12.0) - rspec-expectations (~> 3.12.0) - rspec-mocks (~> 3.12.0) - rspec-core (3.12.2) - rspec-support (~> 3.12.0) - rspec-expectations (3.12.3) + rake (13.2.1) + regexp_parser (2.9.2) + rexml (3.3.2) + strscan + rspec (3.13.0) + rspec-core (~> 3.13.0) + rspec-expectations (~> 3.13.0) + rspec-mocks (~> 3.13.0) + rspec-core (3.13.0) + rspec-support (~> 3.13.0) + rspec-expectations (3.13.1) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.12.0) - rspec-mocks (3.12.6) + rspec-support (~> 3.13.0) + rspec-mocks (3.13.1) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.12.0) - rspec-support (3.12.1) - rubocop (1.59.0) + rspec-support (~> 3.13.0) + rspec-support (3.13.1) + rubocop (1.64.1) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) - parser (>= 3.2.2.4) + parser (>= 3.3.0.2) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 1.8, < 3.0) rexml (>= 3.2.5, < 4.0) - rubocop-ast (>= 1.30.0, < 2.0) + rubocop-ast (>= 1.31.1, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 3.0) - rubocop-ast (1.30.0) - parser (>= 3.2.1.0) - rubocop-capybara (2.20.0) - rubocop (~> 1.41) - rubocop-factory_bot (2.25.1) - rubocop (~> 1.41) - rubocop-performance (1.20.2) + rubocop-ast (1.31.3) + parser (>= 3.3.1.0) + rubocop-performance (1.21.1) rubocop (>= 1.48.1, < 2.0) - rubocop-ast (>= 1.30.0, < 2.0) - rubocop-rspec (2.26.1) - rubocop (~> 1.40) - rubocop-capybara (~> 2.17) - rubocop-factory_bot (~> 2.22) + rubocop-ast (>= 1.31.1, < 2.0) + rubocop-rspec (3.0.3) + rubocop (~> 1.61) ruby-progressbar (1.13.0) ruby2_keywords (0.0.5) sqlite3 (1.7.3) mini_portile2 (~> 2.8.0) - standard (1.33.0) + standard (1.37.0) language_server-protocol (~> 3.17.0.2) lint_roller (~> 1.0) - rubocop (~> 1.59.0) + rubocop (~> 1.64.0) standard-custom (~> 1.0.0) - standard-performance (~> 1.3) + standard-performance (~> 1.4) standard-custom (1.0.2) lint_roller (~> 1.0) rubocop (~> 1.50) - standard-performance (1.3.1) + standard-performance (1.4.0) lint_roller (~> 1.1) - rubocop-performance (~> 1.20.2) - thor (1.3.0) + rubocop-performance (~> 1.21.0) + strscan (3.1.0) + thor (1.3.1) tzinfo (2.0.6) concurrent-ruby (~> 1.0) unicode-display_width (2.5.0) - webmock (3.19.1) + webmock (3.23.1) addressable (>= 2.8.0) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) - yard (0.9.34) - zeitwerk (2.6.12) + yard (0.9.36) + zeitwerk (2.6.16) PLATFORMS x86_64-linux diff --git a/ci/Gemfile.rails-6.1.lock b/ci/Gemfile.rails-6.1.lock index 5c92bff..05e889b 100644 --- a/ci/Gemfile.rails-6.1.lock +++ b/ci/Gemfile.rails-6.1.lock @@ -1,136 +1,139 @@ PATH remote: .. specs: - esse-active_record (0.3.4) + esse-active_record (0.3.5) activerecord (>= 4.2, < 8) esse (>= 0.3.0) GEM remote: https://rubygems.org/ specs: - activemodel (6.1.7.6) - activesupport (= 6.1.7.6) - activerecord (6.1.7.6) - activemodel (= 6.1.7.6) - activesupport (= 6.1.7.6) - activesupport (6.1.7.6) + activemodel (6.1.7.8) + activesupport (= 6.1.7.8) + activerecord (6.1.7.8) + activemodel (= 6.1.7.8) + activesupport (= 6.1.7.8) + activesupport (6.1.7.8) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 1.6, < 2) minitest (>= 5.1) tzinfo (~> 2.0) zeitwerk (~> 2.3) - addressable (2.8.6) - public_suffix (>= 2.0.2, < 6.0) + addressable (2.8.7) + public_suffix (>= 2.0.2, < 7.0) ast (2.4.2) awesome_print (1.9.2) + base64 (0.2.0) + bigdecimal (3.1.8) coderay (1.1.3) - concurrent-ruby (1.2.3) - crack (0.4.5) + concurrent-ruby (1.3.3) + crack (1.0.0) + bigdecimal rexml - diff-lcs (1.5.0) + diff-lcs (1.5.1) dotenv (2.8.1) - elasticsearch (7.17.10) - elasticsearch-api (= 7.17.10) - elasticsearch-transport (= 7.17.10) - elasticsearch-api (7.17.10) + elasticsearch (7.17.11) + elasticsearch-api (= 7.17.11) + elasticsearch-transport (= 7.17.11) + elasticsearch-api (7.17.11) multi_json - elasticsearch-transport (7.17.10) + elasticsearch-transport (7.17.11) + base64 faraday (>= 1, < 3) multi_json - esse (0.3.0) + esse (0.3.4) multi_json thor (>= 0.19) esse-rspec (0.0.6) esse (>= 0.2.4) rspec (>= 3) - faraday (2.0.0) + faraday (2.8.1) + base64 + faraday-net_http (>= 2.0, < 3.1) ruby2_keywords (>= 0.0.4) + faraday-net_http (3.0.2) hashdiff (1.1.0) - i18n (1.14.1) + i18n (1.14.5) concurrent-ruby (~> 1.0) - json (2.7.1) + json (2.7.2) language_server-protocol (3.17.0.3) lint_roller (1.1.0) - method_source (1.0.0) + method_source (1.1.0) mini_portile2 (2.8.7) - minitest (5.21.2) + minitest (5.24.1) multi_json (1.15.0) - parallel (1.24.0) - parser (3.3.0.5) + parallel (1.25.1) + parser (3.3.4.0) ast (~> 2.4.1) racc pry (0.14.2) coderay (~> 1.1) method_source (~> 1.0) - public_suffix (5.0.4) - racc (1.7.3) + public_suffix (5.1.1) + racc (1.8.0) rainbow (3.1.1) - rake (13.1.0) - regexp_parser (2.9.0) - rexml (3.2.6) - rspec (3.12.0) - rspec-core (~> 3.12.0) - rspec-expectations (~> 3.12.0) - rspec-mocks (~> 3.12.0) - rspec-core (3.12.2) - rspec-support (~> 3.12.0) - rspec-expectations (3.12.3) + rake (13.2.1) + regexp_parser (2.9.2) + rexml (3.3.2) + strscan + rspec (3.13.0) + rspec-core (~> 3.13.0) + rspec-expectations (~> 3.13.0) + rspec-mocks (~> 3.13.0) + rspec-core (3.13.0) + rspec-support (~> 3.13.0) + rspec-expectations (3.13.1) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.12.0) - rspec-mocks (3.12.6) + rspec-support (~> 3.13.0) + rspec-mocks (3.13.1) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.12.0) - rspec-support (3.12.1) - rubocop (1.59.0) + rspec-support (~> 3.13.0) + rspec-support (3.13.1) + rubocop (1.64.1) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) - parser (>= 3.2.2.4) + parser (>= 3.3.0.2) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 1.8, < 3.0) rexml (>= 3.2.5, < 4.0) - rubocop-ast (>= 1.30.0, < 2.0) + rubocop-ast (>= 1.31.1, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 3.0) - rubocop-ast (1.30.0) - parser (>= 3.2.1.0) - rubocop-capybara (2.20.0) - rubocop (~> 1.41) - rubocop-factory_bot (2.25.1) - rubocop (~> 1.41) - rubocop-performance (1.20.2) + rubocop-ast (1.31.3) + parser (>= 3.3.1.0) + rubocop-performance (1.21.1) rubocop (>= 1.48.1, < 2.0) - rubocop-ast (>= 1.30.0, < 2.0) - rubocop-rspec (2.26.1) - rubocop (~> 1.40) - rubocop-capybara (~> 2.17) - rubocop-factory_bot (~> 2.22) + rubocop-ast (>= 1.31.1, < 2.0) + rubocop-rspec (3.0.3) + rubocop (~> 1.61) ruby-progressbar (1.13.0) ruby2_keywords (0.0.5) sqlite3 (1.7.3) mini_portile2 (~> 2.8.0) - standard (1.33.0) + standard (1.37.0) language_server-protocol (~> 3.17.0.2) lint_roller (~> 1.0) - rubocop (~> 1.59.0) + rubocop (~> 1.64.0) standard-custom (~> 1.0.0) - standard-performance (~> 1.3) + standard-performance (~> 1.4) standard-custom (1.0.2) lint_roller (~> 1.0) rubocop (~> 1.50) - standard-performance (1.3.1) + standard-performance (1.4.0) lint_roller (~> 1.1) - rubocop-performance (~> 1.20.2) - thor (1.3.0) + rubocop-performance (~> 1.21.0) + strscan (3.1.0) + thor (1.3.1) tzinfo (2.0.6) concurrent-ruby (~> 1.0) unicode-display_width (2.5.0) - webmock (3.19.1) + webmock (3.23.1) addressable (>= 2.8.0) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) - yard (0.9.34) - zeitwerk (2.6.12) + yard (0.9.36) + zeitwerk (2.6.16) PLATFORMS x86_64-linux diff --git a/ci/Gemfile.rails-7.0.lock b/ci/Gemfile.rails-7.0.lock index 6d1bf5a..474f759 100644 --- a/ci/Gemfile.rails-7.0.lock +++ b/ci/Gemfile.rails-7.0.lock @@ -1,136 +1,139 @@ PATH remote: .. specs: - esse-active_record (0.3.4) + esse-active_record (0.3.5) activerecord (>= 4.2, < 8) esse (>= 0.3.0) GEM remote: https://rubygems.org/ specs: - activemodel (6.1.7.6) - activesupport (= 6.1.7.6) - activerecord (6.1.7.6) - activemodel (= 6.1.7.6) - activesupport (= 6.1.7.6) - activesupport (6.1.7.6) + activemodel (6.1.7.8) + activesupport (= 6.1.7.8) + activerecord (6.1.7.8) + activemodel (= 6.1.7.8) + activesupport (= 6.1.7.8) + activesupport (6.1.7.8) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 1.6, < 2) minitest (>= 5.1) tzinfo (~> 2.0) zeitwerk (~> 2.3) - addressable (2.8.6) - public_suffix (>= 2.0.2, < 6.0) + addressable (2.8.7) + public_suffix (>= 2.0.2, < 7.0) ast (2.4.2) awesome_print (1.9.2) + base64 (0.2.0) + bigdecimal (3.1.8) coderay (1.1.3) - concurrent-ruby (1.2.3) - crack (0.4.5) + concurrent-ruby (1.3.3) + crack (1.0.0) + bigdecimal rexml - diff-lcs (1.5.0) + diff-lcs (1.5.1) dotenv (2.8.1) - elasticsearch (7.17.10) - elasticsearch-api (= 7.17.10) - elasticsearch-transport (= 7.17.10) - elasticsearch-api (7.17.10) + elasticsearch (7.17.11) + elasticsearch-api (= 7.17.11) + elasticsearch-transport (= 7.17.11) + elasticsearch-api (7.17.11) multi_json - elasticsearch-transport (7.17.10) + elasticsearch-transport (7.17.11) + base64 faraday (>= 1, < 3) multi_json - esse (0.3.0) + esse (0.3.4) multi_json thor (>= 0.19) esse-rspec (0.0.6) esse (>= 0.2.4) rspec (>= 3) - faraday (2.0.0) + faraday (2.8.1) + base64 + faraday-net_http (>= 2.0, < 3.1) ruby2_keywords (>= 0.0.4) + faraday-net_http (3.0.2) hashdiff (1.1.0) - i18n (1.14.1) + i18n (1.14.5) concurrent-ruby (~> 1.0) - json (2.7.1) + json (2.7.2) language_server-protocol (3.17.0.3) lint_roller (1.1.0) - method_source (1.0.0) + method_source (1.1.0) mini_portile2 (2.8.7) - minitest (5.21.2) + minitest (5.24.1) multi_json (1.15.0) - parallel (1.24.0) - parser (3.3.0.5) + parallel (1.25.1) + parser (3.3.4.0) ast (~> 2.4.1) racc pry (0.14.2) coderay (~> 1.1) method_source (~> 1.0) - public_suffix (5.0.4) - racc (1.7.3) + public_suffix (5.1.1) + racc (1.8.0) rainbow (3.1.1) - rake (13.1.0) - regexp_parser (2.9.0) - rexml (3.2.6) - rspec (3.12.0) - rspec-core (~> 3.12.0) - rspec-expectations (~> 3.12.0) - rspec-mocks (~> 3.12.0) - rspec-core (3.12.2) - rspec-support (~> 3.12.0) - rspec-expectations (3.12.3) + rake (13.2.1) + regexp_parser (2.9.2) + rexml (3.3.2) + strscan + rspec (3.13.0) + rspec-core (~> 3.13.0) + rspec-expectations (~> 3.13.0) + rspec-mocks (~> 3.13.0) + rspec-core (3.13.0) + rspec-support (~> 3.13.0) + rspec-expectations (3.13.1) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.12.0) - rspec-mocks (3.12.6) + rspec-support (~> 3.13.0) + rspec-mocks (3.13.1) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.12.0) - rspec-support (3.12.1) - rubocop (1.59.0) + rspec-support (~> 3.13.0) + rspec-support (3.13.1) + rubocop (1.64.1) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) - parser (>= 3.2.2.4) + parser (>= 3.3.0.2) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 1.8, < 3.0) rexml (>= 3.2.5, < 4.0) - rubocop-ast (>= 1.30.0, < 2.0) + rubocop-ast (>= 1.31.1, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 3.0) - rubocop-ast (1.30.0) - parser (>= 3.2.1.0) - rubocop-capybara (2.20.0) - rubocop (~> 1.41) - rubocop-factory_bot (2.25.1) - rubocop (~> 1.41) - rubocop-performance (1.20.2) + rubocop-ast (1.31.3) + parser (>= 3.3.1.0) + rubocop-performance (1.21.1) rubocop (>= 1.48.1, < 2.0) - rubocop-ast (>= 1.30.0, < 2.0) - rubocop-rspec (2.26.1) - rubocop (~> 1.40) - rubocop-capybara (~> 2.17) - rubocop-factory_bot (~> 2.22) + rubocop-ast (>= 1.31.1, < 2.0) + rubocop-rspec (3.0.3) + rubocop (~> 1.61) ruby-progressbar (1.13.0) ruby2_keywords (0.0.5) sqlite3 (1.7.3) mini_portile2 (~> 2.8.0) - standard (1.33.0) + standard (1.37.0) language_server-protocol (~> 3.17.0.2) lint_roller (~> 1.0) - rubocop (~> 1.59.0) + rubocop (~> 1.64.0) standard-custom (~> 1.0.0) - standard-performance (~> 1.3) + standard-performance (~> 1.4) standard-custom (1.0.2) lint_roller (~> 1.0) rubocop (~> 1.50) - standard-performance (1.3.1) + standard-performance (1.4.0) lint_roller (~> 1.1) - rubocop-performance (~> 1.20.2) - thor (1.3.0) + rubocop-performance (~> 1.21.0) + strscan (3.1.0) + thor (1.3.1) tzinfo (2.0.6) concurrent-ruby (~> 1.0) unicode-display_width (2.5.0) - webmock (3.19.1) + webmock (3.23.1) addressable (>= 2.8.0) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) - yard (0.9.34) - zeitwerk (2.6.12) + yard (0.9.36) + zeitwerk (2.6.16) PLATFORMS x86_64-linux diff --git a/ci/Gemfile.rails-7.1.lock b/ci/Gemfile.rails-7.1.lock index fd1ad34..a6d6f56 100644 --- a/ci/Gemfile.rails-7.1.lock +++ b/ci/Gemfile.rails-7.1.lock @@ -1,20 +1,20 @@ PATH remote: .. specs: - esse-active_record (0.3.4) + esse-active_record (0.3.5) activerecord (>= 4.2, < 8) esse (>= 0.3.0) GEM remote: https://rubygems.org/ specs: - activemodel (7.1.3) - activesupport (= 7.1.3) - activerecord (7.1.3) - activemodel (= 7.1.3) - activesupport (= 7.1.3) + activemodel (7.1.3.4) + activesupport (= 7.1.3.4) + activerecord (7.1.3.4) + activemodel (= 7.1.3.4) + activesupport (= 7.1.3.4) timeout (>= 0.4.0) - activesupport (7.1.3) + activesupport (7.1.3.4) base64 bigdecimal concurrent-ruby (~> 1.0, >= 1.0.2) @@ -24,124 +24,124 @@ GEM minitest (>= 5.1) mutex_m tzinfo (~> 2.0) - addressable (2.8.6) - public_suffix (>= 2.0.2, < 6.0) + addressable (2.8.7) + public_suffix (>= 2.0.2, < 7.0) ast (2.4.2) awesome_print (1.9.2) base64 (0.2.0) - bigdecimal (3.1.6) + bigdecimal (3.1.8) coderay (1.1.3) - concurrent-ruby (1.2.3) + concurrent-ruby (1.3.3) connection_pool (2.4.1) - crack (0.4.5) + crack (1.0.0) + bigdecimal rexml - diff-lcs (1.5.0) + diff-lcs (1.5.1) dotenv (2.8.1) - drb (2.2.0) - ruby2_keywords - elasticsearch (7.17.10) - elasticsearch-api (= 7.17.10) - elasticsearch-transport (= 7.17.10) - elasticsearch-api (7.17.10) + drb (2.2.1) + elasticsearch (7.17.11) + elasticsearch-api (= 7.17.11) + elasticsearch-transport (= 7.17.11) + elasticsearch-api (7.17.11) multi_json - elasticsearch-transport (7.17.10) + elasticsearch-transport (7.17.11) + base64 faraday (>= 1, < 3) multi_json - esse (0.3.0) + esse (0.3.4) multi_json thor (>= 0.19) esse-rspec (0.0.6) esse (>= 0.2.4) rspec (>= 3) - faraday (2.0.0) + faraday (2.8.1) + base64 + faraday-net_http (>= 2.0, < 3.1) ruby2_keywords (>= 0.0.4) + faraday-net_http (3.0.2) hashdiff (1.1.0) - i18n (1.14.1) + i18n (1.14.5) concurrent-ruby (~> 1.0) - json (2.7.1) + json (2.7.2) language_server-protocol (3.17.0.3) lint_roller (1.1.0) - method_source (1.0.0) + method_source (1.1.0) mini_portile2 (2.8.7) - minitest (5.21.2) + minitest (5.24.1) multi_json (1.15.0) mutex_m (0.2.0) - parallel (1.24.0) - parser (3.3.0.5) + parallel (1.25.1) + parser (3.3.4.0) ast (~> 2.4.1) racc pry (0.14.2) coderay (~> 1.1) method_source (~> 1.0) - public_suffix (5.0.4) - racc (1.7.3) + public_suffix (5.1.1) + racc (1.8.0) rainbow (3.1.1) - rake (13.1.0) - regexp_parser (2.9.0) - rexml (3.2.6) - rspec (3.12.0) - rspec-core (~> 3.12.0) - rspec-expectations (~> 3.12.0) - rspec-mocks (~> 3.12.0) - rspec-core (3.12.2) - rspec-support (~> 3.12.0) - rspec-expectations (3.12.3) + rake (13.2.1) + regexp_parser (2.9.2) + rexml (3.3.2) + strscan + rspec (3.13.0) + rspec-core (~> 3.13.0) + rspec-expectations (~> 3.13.0) + rspec-mocks (~> 3.13.0) + rspec-core (3.13.0) + rspec-support (~> 3.13.0) + rspec-expectations (3.13.1) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.12.0) - rspec-mocks (3.12.6) + rspec-support (~> 3.13.0) + rspec-mocks (3.13.1) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.12.0) - rspec-support (3.12.1) - rubocop (1.59.0) + rspec-support (~> 3.13.0) + rspec-support (3.13.1) + rubocop (1.64.1) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) - parser (>= 3.2.2.4) + parser (>= 3.3.0.2) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 1.8, < 3.0) rexml (>= 3.2.5, < 4.0) - rubocop-ast (>= 1.30.0, < 2.0) + rubocop-ast (>= 1.31.1, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 3.0) - rubocop-ast (1.30.0) - parser (>= 3.2.1.0) - rubocop-capybara (2.20.0) - rubocop (~> 1.41) - rubocop-factory_bot (2.25.1) - rubocop (~> 1.41) - rubocop-performance (1.20.2) + rubocop-ast (1.31.3) + parser (>= 3.3.1.0) + rubocop-performance (1.21.1) rubocop (>= 1.48.1, < 2.0) - rubocop-ast (>= 1.30.0, < 2.0) - rubocop-rspec (2.26.1) - rubocop (~> 1.40) - rubocop-capybara (~> 2.17) - rubocop-factory_bot (~> 2.22) + rubocop-ast (>= 1.31.1, < 2.0) + rubocop-rspec (3.0.3) + rubocop (~> 1.61) ruby-progressbar (1.13.0) ruby2_keywords (0.0.5) sqlite3 (1.7.3) mini_portile2 (~> 2.8.0) - standard (1.33.0) + standard (1.37.0) language_server-protocol (~> 3.17.0.2) lint_roller (~> 1.0) - rubocop (~> 1.59.0) + rubocop (~> 1.64.0) standard-custom (~> 1.0.0) - standard-performance (~> 1.3) + standard-performance (~> 1.4) standard-custom (1.0.2) lint_roller (~> 1.0) rubocop (~> 1.50) - standard-performance (1.3.1) + standard-performance (1.4.0) lint_roller (~> 1.1) - rubocop-performance (~> 1.20.2) - thor (1.3.0) + rubocop-performance (~> 1.21.0) + strscan (3.1.0) + thor (1.3.1) timeout (0.4.1) tzinfo (2.0.6) concurrent-ruby (~> 1.0) unicode-display_width (2.5.0) - webmock (3.19.1) + webmock (3.23.1) addressable (>= 2.8.0) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) - yard (0.9.34) + yard (0.9.36) PLATFORMS x86_64-linux diff --git a/lib/esse/active_record/callbacks.rb b/lib/esse/active_record/callbacks.rb index 9890341..e5f3873 100644 --- a/lib/esse/active_record/callbacks.rb +++ b/lib/esse/active_record/callbacks.rb @@ -27,7 +27,7 @@ def register_callback(identifier, operation, callback_class) raise ArgumentError, 'callback_class must be a subclass of Esse::ActiveRecord::Callback' end - key = :"#{identifier}_on_#{operation}" + key = [operation, identifier].join('_').to_sym @callbacks = @callbacks ? @callbacks.dup : {} if @callbacks.key?(key) @@ -42,11 +42,12 @@ def register_callback(identifier, operation, callback_class) def registered?(identifier, operation) return false unless @callbacks - @callbacks.key?(:"#{identifier}_on_#{operation}") + key = [operation, identifier].join('_').to_sym + @callbacks.key?(key) end def fetch!(identifier, operation) - key = :"#{identifier}_on_#{operation}" + key = [operation, identifier].join('_').to_sym if registered?(identifier, operation) [key, @callbacks[key]] else diff --git a/lib/esse/active_record/callbacks/indexing_on_create.rb b/lib/esse/active_record/callbacks/indexing_on_create.rb index 19b3a0c..f987506 100644 --- a/lib/esse/active_record/callbacks/indexing_on_create.rb +++ b/lib/esse/active_record/callbacks/indexing_on_create.rb @@ -6,7 +6,7 @@ class IndexingOnCreate < Callback def call(model) record = block_result || model document = repo.serialize(record) - repo.index.index(document, **options) if document + repo.index.index(document, **options) if document && !document.ignore_on_index? true end end diff --git a/lib/esse/active_record/callbacks/indexing_on_destroy.rb b/lib/esse/active_record/callbacks/indexing_on_destroy.rb index d092b9f..0913614 100644 --- a/lib/esse/active_record/callbacks/indexing_on_destroy.rb +++ b/lib/esse/active_record/callbacks/indexing_on_destroy.rb @@ -6,7 +6,7 @@ class IndexingOnDestroy < Callback def call(model) record = block_result || model document = repo.serialize(record) - repo.index.delete(document, **options) if document + repo.index.delete(document, **options) if document && !document.ignore_on_delete? true rescue Esse::Transport::NotFoundError true diff --git a/lib/esse/active_record/callbacks/indexing_on_update.rb b/lib/esse/active_record/callbacks/indexing_on_update.rb index 99ca182..0901b38 100644 --- a/lib/esse/active_record/callbacks/indexing_on_update.rb +++ b/lib/esse/active_record/callbacks/indexing_on_update.rb @@ -41,6 +41,8 @@ def call(model) protected def update_document(document) + return if document.ignore_on_index? + if update_with == :update begin repo.index.update(document, **options) diff --git a/lib/esse/active_record/collection.rb b/lib/esse/active_record/collection.rb index 6a7cb8f..06b0a65 100644 --- a/lib/esse/active_record/collection.rb +++ b/lib/esse/active_record/collection.rb @@ -83,6 +83,17 @@ def each end end + def each_batch_ids + dataset.select(:id).except(:includes, :preload, :eager_load).find_in_batches(**batch_options) do |rows| + yield(rows.map(&:id)) + end + end + + def count + dataset.except(:includes, :preload, :eager_load).count + end + alias_method :size, :count + def dataset(**kwargs) query = self.class.base_scope&.call || raise(NotImplementedError, "No scope defined for #{self.class}") query = query.except(:order, :limit, :offset) diff --git a/lib/esse/active_record/model.rb b/lib/esse/active_record/model.rb index de60116..f98f795 100644 --- a/lib/esse/active_record/model.rb +++ b/lib/esse/active_record/model.rb @@ -12,7 +12,7 @@ def esse_callbacks @esse_callbacks ||= {}.freeze end - def esse_callback(index_repo_name, operation_name, on: %i[create update destroy], **options, &block) + def esse_callback(index_repo_name, operation_name, on: %i[create update destroy], identifier_suffix: nil, **options, &block) @esse_callbacks = esse_callbacks.dup cb_if = options.delete(:if) cb_unless = options.delete(:unless) @@ -25,6 +25,9 @@ def esse_callback(index_repo_name, operation_name, on: %i[create update destroy] Array(on).each do |event| identifier, klass = Esse::ActiveRecord::Callbacks.fetch!(operation_name, event) + if identifier_suffix + identifier = :"#{identifier}_#{identifier_suffix}" + end if @esse_callbacks.dig(index_repo_name, identifier) raise ArgumentError, format('index repository %p already registered %s operation', name: index_repo_name, op: operation_name) @@ -71,7 +74,7 @@ def index_callback(index_repo_name, on: %i[create update destroy], with: nil, ** def update_lazy_attribute_callback(index_repo_name, attribute_name, on: %i[create update destroy], **options, &block) options[:attribute_name] = attribute_name - esse_callback(index_repo_name, :update_lazy_attribute, on: on, **options, &block) + esse_callback(index_repo_name, :update_lazy_attribute, identifier_suffix: attribute_name.to_sym, on: on, **options, &block) end # Disable indexing for the block execution on model level diff --git a/lib/esse/active_record/version.rb b/lib/esse/active_record/version.rb index 9e5bd0d..c4f0160 100644 --- a/lib/esse/active_record/version.rb +++ b/lib/esse/active_record/version.rb @@ -2,6 +2,6 @@ module Esse module ActiveRecord - VERSION = '0.3.4' + VERSION = '0.3.5' end end diff --git a/lib/esse/plugins/active_record.rb b/lib/esse/plugins/active_record.rb index 5d6e6f2..4bf84a3 100644 --- a/lib/esse/plugins/active_record.rb +++ b/lib/esse/plugins/active_record.rb @@ -11,7 +11,7 @@ module RepositoryClassMethods # @option options [Symbol] :batch_size The batch size for the collection def collection(*args, **kwargs, &block) unless model_or_relation?(args.first) - return super(*args, **kwargs, &block) + return super end model_class = args.shift diff --git a/spec/esse/active_record/callbacks_spec.rb b/spec/esse/active_record/callbacks_spec.rb index 3dd59e7..79f00a2 100644 --- a/spec/esse/active_record/callbacks_spec.rb +++ b/spec/esse/active_record/callbacks_spec.rb @@ -58,7 +58,7 @@ it 'returns the callback class' do klass = Class.new(Esse::ActiveRecord::Callback) described_class.register_callback(:external, :create, klass) - expect(described_class.fetch!(:external, :create)).to eq([:external_on_create, klass]) + expect(described_class.fetch!(:external, :create)).to eq([:create_external, klass]) end end end diff --git a/spec/esse/active_record/collection_spec.rb b/spec/esse/active_record/collection_spec.rb index 37aba75..a5530b4 100644 --- a/spec/esse/active_record/collection_spec.rb +++ b/spec/esse/active_record/collection_spec.rb @@ -97,6 +97,71 @@ end end + describe '#each_batch_ids' do + it 'raises NotImplementedError when scope is not defined on the collection class' do + expect { + collection = described_class.new + collection.each_batch_ids + }.to raise_error(NotImplementedError) + end + + it 'returns an Enumerator with a relation instance' do + collection = Class.new(described_class) + collection.base_scope = -> { Animal.all } + expect { |b| collection.new.each_batch_ids(&b) }.not_to yield_control + end + + context 'with start and batch_size' do + let(:collection_class) do + klass = Class.new(described_class) + klass.base_scope = -> { Dog } + klass + end + + let!(:dogs) do + Array.new(3) { |i| Dog.create!(name: "Dog #{i.next}") } + end + + after do + Dog.destroy_all + end + + it 'stream entity ids in batches according to the :batch_size option' do + instance = collection_class.new(batch_size: 1) + + expect { |b| instance.each_batch_ids(&b) }.to yield_successive_args(*dogs.map { |doc| [doc.id] }) + end + + it 'stream entity ids in batches according to the :batch_size option and :start option' do + instance = collection_class.new(batch_size: 1, start: dogs[1].id) + + expect { |b| instance.each_batch_ids(&b) }.to yield_successive_args(*dogs[1..2].map { |doc| [doc.id] }) + end + + it 'stream entity ids in batches according to the :batch_size option and :finish option' do + instance = collection_class.new(batch_size: 1, finish: dogs[1].id) + + expect { |b| instance.each_batch_ids(&b) }.to yield_successive_args(*dogs[0..1].map { |doc| [doc.id] }) + end + end + end + + describe '#count' do + it 'raises NotImplementedError when scope is not defined on the collection class' do + expect { + collection = described_class.new + collection.count + }.to raise_error(NotImplementedError) + end + + it 'returns the count of the dataset' do + collection = Class.new(described_class) + collection.base_scope = -> { Animal.all } + expect(collection.new.count).to eq(Animal.count) + expect(collection.new.size).to eq(Animal.count) + end + end + describe '#dataset' do it 'returns an ActiveRecord::Relation' do collection = Class.new(described_class) diff --git a/spec/esse/active_record/model/esse_callback_spec.rb b/spec/esse/active_record/model/esse_callback_spec.rb index e301269..9c98703 100644 --- a/spec/esse/active_record/model/esse_callback_spec.rb +++ b/spec/esse/active_record/model/esse_callback_spec.rb @@ -80,8 +80,8 @@ class DumpTempCallbackOnDestroy < DumpTempCallback; end }.not_to raise_error expect(model_class.esse_callbacks).to a_hash_including( 'states:state' => a_hash_including( - temp_on_create: contain_exactly(DumpTempCallbackOnCreate, {}, an_instance_of(Proc)), - temp_on_update: contain_exactly(DumpTempCallbackOnUpdate, {}, an_instance_of(Proc)), + create_temp: contain_exactly(DumpTempCallbackOnCreate, {}, an_instance_of(Proc)), + update_temp: contain_exactly(DumpTempCallbackOnUpdate, {}, an_instance_of(Proc)), ) ) expect(model_class.esse_callbacks).to be_frozen @@ -165,7 +165,7 @@ class DumpTempCallbackOnDestroy < DumpTempCallback; end model_class.esse_callback('states:state', :temp, on: %i[create], custom: 'value') { :ok } expect(model_class.esse_callbacks).to a_hash_including( 'states:state' => a_hash_including( - temp_on_create: contain_exactly(DumpTempCallbackOnCreate, {custom: 'value'}, an_instance_of(Proc)), + create_temp: contain_exactly(DumpTempCallbackOnCreate, {custom: 'value'}, an_instance_of(Proc)), ) ) end @@ -212,7 +212,7 @@ class DumpTempCallbackOnDestroy < DumpTempCallback; end model_class.esse_callback('states:state', :temp, on: %i[update], custom: 'value') { :ok } expect(model_class.esse_callbacks).to a_hash_including( 'states:state' => a_hash_including( - temp_on_update: contain_exactly(DumpTempCallbackOnUpdate, {custom: 'value'}, an_instance_of(Proc)), + update_temp: contain_exactly(DumpTempCallbackOnUpdate, {custom: 'value'}, an_instance_of(Proc)), ) ) end @@ -262,7 +262,7 @@ class DumpTempCallbackOnDestroy < DumpTempCallback; end model_class.esse_callback('states:state', :temp, on: %i[destroy], custom: 'value') { :ok } expect(model_class.esse_callbacks).to a_hash_including( 'states:state' => a_hash_including( - temp_on_destroy: contain_exactly(DumpTempCallbackOnDestroy, {custom: 'value'}, an_instance_of(Proc)), + destroy_temp: contain_exactly(DumpTempCallbackOnDestroy, {custom: 'value'}, an_instance_of(Proc)), ) ) end diff --git a/spec/esse/active_record/model/update_lazy_attribute_callback_spec.rb b/spec/esse/active_record/model/update_lazy_attribute_callback_spec.rb index 2564745..c8dd39a 100644 --- a/spec/esse/active_record/model/update_lazy_attribute_callback_spec.rb +++ b/spec/esse/active_record/model/update_lazy_attribute_callback_spec.rb @@ -34,9 +34,24 @@ model_class.update_lazy_attribute_callback('states:state', :field, custom: 'value') { :ok } expect(model_class.esse_callbacks).to a_hash_including( 'states:state' => a_hash_including( - update_lazy_attribute_on_create: contain_exactly(Esse::ActiveRecord::Callbacks::UpdateLazyAttribute, { attribute_name: :field, custom: 'value'}, an_instance_of(Proc)), - update_lazy_attribute_on_update: contain_exactly(Esse::ActiveRecord::Callbacks::UpdateLazyAttribute, { attribute_name: :field, custom: 'value'}, an_instance_of(Proc)), - update_lazy_attribute_on_destroy: contain_exactly(Esse::ActiveRecord::Callbacks::UpdateLazyAttribute, { attribute_name: :field, custom: 'value'}, an_instance_of(Proc)), + create_update_lazy_attribute_field: contain_exactly(Esse::ActiveRecord::Callbacks::UpdateLazyAttribute, { attribute_name: :field, custom: 'value'}, an_instance_of(Proc)), + update_update_lazy_attribute_field: contain_exactly(Esse::ActiveRecord::Callbacks::UpdateLazyAttribute, { attribute_name: :field, custom: 'value'}, an_instance_of(Proc)), + destroy_update_lazy_attribute_field: contain_exactly(Esse::ActiveRecord::Callbacks::UpdateLazyAttribute, { attribute_name: :field, custom: 'value'}, an_instance_of(Proc)), + ) + ) + end + + it 'registers multiple callbacks to different attributes' do + model_class.update_lazy_attribute_callback('states:state', :field1, custom: 'value1') { :ok } + model_class.update_lazy_attribute_callback('states:state', :field2, custom: 'value2') { :ok } + expect(model_class.esse_callbacks).to a_hash_including( + 'states:state' => a_hash_including( + create_update_lazy_attribute_field1: contain_exactly(Esse::ActiveRecord::Callbacks::UpdateLazyAttribute, { attribute_name: :field1, custom: 'value1'}, an_instance_of(Proc)), + update_update_lazy_attribute_field1: contain_exactly(Esse::ActiveRecord::Callbacks::UpdateLazyAttribute, { attribute_name: :field1, custom: 'value1'}, an_instance_of(Proc)), + destroy_update_lazy_attribute_field1: contain_exactly(Esse::ActiveRecord::Callbacks::UpdateLazyAttribute, { attribute_name: :field1, custom: 'value1'}, an_instance_of(Proc)), + create_update_lazy_attribute_field2: contain_exactly(Esse::ActiveRecord::Callbacks::UpdateLazyAttribute, { attribute_name: :field2, custom: 'value2'}, an_instance_of(Proc)), + update_update_lazy_attribute_field2: contain_exactly(Esse::ActiveRecord::Callbacks::UpdateLazyAttribute, { attribute_name: :field2, custom: 'value2'}, an_instance_of(Proc)), + destroy_update_lazy_attribute_field2: contain_exactly(Esse::ActiveRecord::Callbacks::UpdateLazyAttribute, { attribute_name: :field2, custom: 'value2'}, an_instance_of(Proc)), ) ) end @@ -51,7 +66,7 @@ model_class.update_lazy_attribute_callback('states:state', :field, on: %i[create], custom: 'value') { :ok } expect(model_class.esse_callbacks).to a_hash_including( 'states:state' => a_hash_including( - update_lazy_attribute_on_create: contain_exactly(Esse::ActiveRecord::Callbacks::UpdateLazyAttribute, { attribute_name: :field, custom: 'value'}, an_instance_of(Proc)), + create_update_lazy_attribute_field: contain_exactly(Esse::ActiveRecord::Callbacks::UpdateLazyAttribute, { attribute_name: :field, custom: 'value'}, an_instance_of(Proc)), ) ) end @@ -67,7 +82,7 @@ model_class.update_lazy_attribute_callback('states:state', :field, on: %i[update], custom: 'value') { :ok } expect(model_class.esse_callbacks).to a_hash_including( 'states:state' => a_hash_including( - update_lazy_attribute_on_update: contain_exactly(Esse::ActiveRecord::Callbacks::UpdateLazyAttribute, { attribute_name: :field, custom: 'value'}, an_instance_of(Proc)), + update_update_lazy_attribute_field: contain_exactly(Esse::ActiveRecord::Callbacks::UpdateLazyAttribute, { attribute_name: :field, custom: 'value'}, an_instance_of(Proc)), ) ) end @@ -83,7 +98,7 @@ model_class.update_lazy_attribute_callback('states:state', :field, on: %i[destroy], custom: 'value') { :ok } expect(model_class.esse_callbacks).to a_hash_including( 'states:state' => a_hash_including( - update_lazy_attribute_on_destroy: contain_exactly(Esse::ActiveRecord::Callbacks::UpdateLazyAttribute, { attribute_name: :field, custom: 'value'}, an_instance_of(Proc)), + destroy_update_lazy_attribute_field: contain_exactly(Esse::ActiveRecord::Callbacks::UpdateLazyAttribute, { attribute_name: :field, custom: 'value'}, an_instance_of(Proc)), ) ) end