Skip to content

Commit

Permalink
fix: Gotcha with validation order (#50)
Browse files Browse the repository at this point in the history
  • Loading branch information
jhurd2326 authored Oct 9, 2024
1 parent fb16dda commit aaad007
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 14 deletions.
5 changes: 0 additions & 5 deletions lib/has_state_machine/state.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,6 @@ class State < String
# transactional? - Determines whether or not the transition should happen with a transactional block.
delegate :possible_transitions, :transactional?, :state, to: "self.class"

##
# Add errors to the ActiveRecord object rather than the HasStateMachine::State
# class.
delegate :errors, to: :object

##
# Initializes the HasStateMachine::State instance.
#
Expand Down
7 changes: 6 additions & 1 deletion lib/has_state_machine/state_helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,12 @@ def state_class_defined?
def state_instance_validations
return unless state_class.present?

public_send(state_attribute.to_s).valid?
state_instance = public_send(state_attribute.to_s)
return if state_instance.valid?

state_instance.errors.each do |error|
errors.add(error.attribute, error.type)
end
end
end

Expand Down
35 changes: 35 additions & 0 deletions test/has_state_machine/state_helpers_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
t.string :status
end

ActiveRecord::Migration.create_table :animals, force: true do |t|
t.string :status
end

class Mountain < ActiveRecord::Base
has_state_machine states: %i[foo bar baz]
has_many :trees
Expand All @@ -21,6 +25,16 @@ class Tree < ActiveRecord::Base
belongs_to :mountain
end

class Animal < ActiveRecord::Base
validate :failing_validation

has_state_machine states: %i[foo bar baz]

def failing_validation
errors.add(:fail, "animal is not valid")
end
end

module Workflow
module Mountain
class Foo < HasStateMachine::State
Expand All @@ -39,6 +53,16 @@ module Tree
class Foo < HasStateMachine::State
end
end

module Animal
class Baz < HasStateMachine::State
validate :failing_validation

def failing_validation
errors.add(:base, "dummy validation failed")
end
end
end
end

class HasStateMachine::StateHelpersTest < ActiveSupport::TestCase
Expand Down Expand Up @@ -82,6 +106,17 @@ class HasStateMachine::StateHelpersTest < ActiveSupport::TestCase

assert subject.valid?
end

describe "object also contains errors" do
subject { Animal.new }

it "does not remove already existing errors from the object if state also has errors" do
subject.status = "baz"
refute subject.valid?

assert subject.errors.to_a.length == 2
end
end
end

describe "state attribute method" do
Expand Down
8 changes: 0 additions & 8 deletions test/has_state_machine/state_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -79,14 +79,6 @@ class HasStateMachine::StateTest < ActiveSupport::TestCase
it { assert_equal %w[swimming floating tanning tubing lotioning], subject.possible_transitions }
end

describe "#errors" do
it "delegates to the object" do
object.errors.add(:base, "foobar")

assert_equal({base: %w[foobar]}, subject.errors.messages)
end
end

describe "#transition_to" do
describe "callbacks" do
it "runs before_transition callbacks" do
Expand Down

0 comments on commit aaad007

Please sign in to comment.