Skip to content

Commit

Permalink
Stop preconditions from being executed twice (#130)
Browse files Browse the repository at this point in the history
  • Loading branch information
lstrzebinczyk authored Aug 29, 2024
1 parent d1fecea commit 95daead
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 6 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
## Next

## v0.17.3

* Stopped preconditions from being executed twice on `#try_perform!`

## v0.17.2

* Deprecate `Granite::Action#perform` in favor of using `Granite::Action#try_perform!`, as these 2 methods are basically identical. It will be removed in next major version. (https://github.com/toptal/granite/pull/117)
Expand Down
2 changes: 1 addition & 1 deletion lib/granite/action/performing.rb
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ def perform!(context: nil, **options)
# @raise [Granite::Action::ValidationError] Action or associated objects are invalid
# @raise [NotImplementedError] execute_perform! method was not defined yet
def try_perform!(context: nil, **options)
return unless satisfy_preconditions?
return unless satisfy_preconditions?(cache_result: true)

transaction do
validate!(context)
Expand Down
10 changes: 6 additions & 4 deletions lib/granite/action/preconditions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -85,16 +85,17 @@ def add_precondition(klass, *args, &block)

def initialize(*)
@failed_preconditions = []
@preconditions_run = nil
super
end

# Check if all preconditions are satisfied
#
# @return [Boolean] wheter all preconditions are satisfied
def satisfy_preconditions?
def satisfy_preconditions?(cache_result: false)
errors.clear
failed_preconditions.clear
run_preconditions!
run_preconditions!(cache_result: cache_result)
end

# Adds passed error message and options to `errors` object
Expand All @@ -105,8 +106,9 @@ def decline_with(*args, **kwargs)

private

def run_preconditions!
_preconditions.execute! self
def run_preconditions!(cache_result: false)
_preconditions.execute!(self) if @preconditions_run.nil?
@preconditions_run = true if cache_result
errors.empty?
end

Expand Down
2 changes: 1 addition & 1 deletion lib/granite/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module Granite
VERSION = '0.17.2'.freeze
VERSION = '0.17.3'.freeze
end
31 changes: 31 additions & 0 deletions spec/lib/granite/action/performing_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,37 @@ def execute_perform!(*)
end

describe '#try_perform!' do
context 'when checking preconditions run count' do
let(:action) { Action.new(user) }

before do
stub_class(:action, Granite::Action) do
subject :user, class_name: 'DummyUser'

allow_if { true }

attr_accessor :preconditions_run_count

precondition do
@preconditions_run_count ||= 0
@preconditions_run_count += 1
end

private

def execute_perform!(*)
false
end
end
end

it 'runs preconditions only once' do
action.try_perform!

expect(action.preconditions_run_count).to eq(1)
end
end

context 'with login' do
let(:action) { Action.new(user, login: 'Login') }

Expand Down

0 comments on commit 95daead

Please sign in to comment.