From 22fca2bb20e38903bfa013707dcadf4b57c2358b Mon Sep 17 00:00:00 2001 From: "Marcos G. Zimmermann" Date: Thu, 11 Jul 2024 13:40:47 -0300 Subject: [PATCH] feat: extend callbacks to support :if and :unless (#9) --- Gemfile | 2 +- Gemfile.lock | 6 +- ci/Gemfile.rails-5.2.lock | 2 +- ci/Gemfile.rails-6.0.lock | 2 +- ci/Gemfile.rails-6.1.lock | 2 +- ci/Gemfile.rails-7.0.lock | 2 +- ci/Gemfile.rails-7.1.lock | 2 +- lib/esse/active_record/model.rb | 9 ++- lib/esse/active_record/version.rb | 2 +- .../active_record/model/esse_callback_spec.rb | 61 +++++++++++++++++++ 10 files changed, 79 insertions(+), 11 deletions(-) diff --git a/Gemfile b/Gemfile index 3afd56b..1a0887d 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.0' +gem 'esse', '~> 0.3.1' gem 'sqlite3', '~> 1.7.3' gem 'activerecord', '~> 5.2' gem 'esse-rspec', '~> 0.0.6' diff --git a/Gemfile.lock b/Gemfile.lock index 810a004..789cbf8 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - esse-active_record (0.3.2) + esse-active_record (0.3.3) 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.0) + esse (0.3.1) 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.0) + esse (~> 0.3.1) 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 b81bf79..347d3b8 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.2) + esse-active_record (0.3.3) activerecord (>= 4.2, < 8) esse (>= 0.3.0) diff --git a/ci/Gemfile.rails-6.0.lock b/ci/Gemfile.rails-6.0.lock index 863ddc6..e808b40 100644 --- a/ci/Gemfile.rails-6.0.lock +++ b/ci/Gemfile.rails-6.0.lock @@ -1,7 +1,7 @@ PATH remote: .. specs: - esse-active_record (0.3.2) + esse-active_record (0.3.3) activerecord (>= 4.2, < 8) esse (>= 0.3.0) diff --git a/ci/Gemfile.rails-6.1.lock b/ci/Gemfile.rails-6.1.lock index b475fae..0a95807 100644 --- a/ci/Gemfile.rails-6.1.lock +++ b/ci/Gemfile.rails-6.1.lock @@ -1,7 +1,7 @@ PATH remote: .. specs: - esse-active_record (0.3.2) + esse-active_record (0.3.3) activerecord (>= 4.2, < 8) esse (>= 0.3.0) diff --git a/ci/Gemfile.rails-7.0.lock b/ci/Gemfile.rails-7.0.lock index 863ddc6..e808b40 100644 --- a/ci/Gemfile.rails-7.0.lock +++ b/ci/Gemfile.rails-7.0.lock @@ -1,7 +1,7 @@ PATH remote: .. specs: - esse-active_record (0.3.2) + esse-active_record (0.3.3) activerecord (>= 4.2, < 8) esse (>= 0.3.0) diff --git a/ci/Gemfile.rails-7.1.lock b/ci/Gemfile.rails-7.1.lock index e91bf59..6a1cdde 100644 --- a/ci/Gemfile.rails-7.1.lock +++ b/ci/Gemfile.rails-7.1.lock @@ -1,7 +1,7 @@ PATH remote: .. specs: - esse-active_record (0.3.2) + esse-active_record (0.3.3) activerecord (>= 4.2, < 8) esse (>= 0.3.0) diff --git a/lib/esse/active_record/model.rb b/lib/esse/active_record/model.rb index bb43be0..de60116 100644 --- a/lib/esse/active_record/model.rb +++ b/lib/esse/active_record/model.rb @@ -14,7 +14,14 @@ def esse_callbacks def esse_callback(index_repo_name, operation_name, on: %i[create update destroy], **options, &block) @esse_callbacks = esse_callbacks.dup - if_enabled = -> { Esse::ActiveRecord::Hooks.enabled?(index_repo_name) && Esse::ActiveRecord::Hooks.enabled_for_model?(self.class, index_repo_name) } + cb_if = options.delete(:if) + cb_unless = options.delete(:unless) + if_enabled = -> { + (cb_if.nil? || (cb_if.respond_to?(:call) ? instance_exec(&cb_if) : send(cb_if))) && + (cb_unless.nil? || (cb_unless.respond_to?(:call) ? !instance_exec(&cb_unless) : !send(cb_unless))) && + Esse::ActiveRecord::Hooks.enabled?(index_repo_name) && + Esse::ActiveRecord::Hooks.enabled_for_model?(self.class, index_repo_name) + } Array(on).each do |event| identifier, klass = Esse::ActiveRecord::Callbacks.fetch!(operation_name, event) diff --git a/lib/esse/active_record/version.rb b/lib/esse/active_record/version.rb index 676f809..011f67a 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.2' + VERSION = '0.3.3' end end diff --git a/spec/esse/active_record/model/esse_callback_spec.rb b/spec/esse/active_record/model/esse_callback_spec.rb index 6551d4d..e301269 100644 --- a/spec/esse/active_record/model/esse_callback_spec.rb +++ b/spec/esse/active_record/model/esse_callback_spec.rb @@ -88,6 +88,67 @@ class DumpTempCallbackOnDestroy < DumpTempCallback; end expect(model_class.esse_callbacks['states:state']).to be_frozen end + context 'when passing :if option' do + it 'allows to set custom condition using proc' do + model_class.esse_callback('states:state', :temp, on: :create, if: -> { name == 'TRUE' }) { :ok } + + model = build_record(model_class, name: 'FALSE') + expect { model.save }.not_to change { DummyCallbackRepo.all.size } + + model = build_record(model_class, name: 'TRUE') + expect { model.save }.to change { DummyCallbackRepo.all.size }.by(1) + end + + it 'allows to set custom condition using method' do + model_class.esse_callback('states:state', :temp, on: :create, if: :true?) { :ok } + + model = build_record(model_class, name: 'FALSE') + model.define_singleton_method(:true?) { false } + expect { model.save }.not_to change { DummyCallbackRepo.all.size } + + model = build_record(model_class, name: 'TRUE') + model.define_singleton_method(:true?) { true } + expect { model.save }.to change { DummyCallbackRepo.all.size }.by(1) + end + + it 'does not override hooks condition' do + model_class.esse_callback('states:state', :temp, on: :create, if: -> { name == 'TRUE' }) { :ok } + model = build_record(model_class, name: 'TRUE') + expect { model_class.without_indexing { model.save } }.not_to change { DummyCallbackRepo.all.size } + end + end + + context 'when passing :unless option' do + it 'allows to set custom condition using proc' do + model_class.esse_callback('states:state', :temp, on: :create, unless: -> { name == 'TRUE' }) { :ok } + + model = build_record(model_class, name: 'FALSE') + expect { model.save }.to change { DummyCallbackRepo.all.size }.by(1) + + model = build_record(model_class, name: 'TRUE') + expect { model.save }.not_to change { DummyCallbackRepo.all.size } + end + + it 'allows to set custom condition using method' do + model_class.esse_callback('states:state', :temp, on: :create, unless: :true?) { :ok } + + model = build_record(model_class, name: 'FALSE') + model.define_singleton_method(:true?) { false } + expect { model.save }.to change { DummyCallbackRepo.all.size }.by(1) + + model = build_record(model_class, name: 'TRUE') + model.define_singleton_method(:true?) { true } + expect { model.save }.not_to change { DummyCallbackRepo.all.size } + end + + it 'does not override hooks condition' do + model_class.esse_callback('states:state', :temp, on: :create, unless: -> { name == 'TRUE' }) { :ok } + model = build_record(model_class, name: 'FALSE') + + expect { model_class.without_indexing { model.save } }.not_to change { DummyCallbackRepo.all.size } + end + end + context 'when on :create' do it 'raises an error when the callback is not registered' do expect {