diff --git a/lib/has_state_machine/state.rb b/lib/has_state_machine/state.rb index 2025e03..4cc0b67 100644 --- a/lib/has_state_machine/state.rb +++ b/lib/has_state_machine/state.rb @@ -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. # diff --git a/lib/has_state_machine/state_helpers.rb b/lib/has_state_machine/state_helpers.rb index a8a491f..7d044ac 100644 --- a/lib/has_state_machine/state_helpers.rb +++ b/lib/has_state_machine/state_helpers.rb @@ -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 diff --git a/test/has_state_machine/state_helpers_test.rb b/test/has_state_machine/state_helpers_test.rb index ed06e26..8f7f905 100644 --- a/test/has_state_machine/state_helpers_test.rb +++ b/test/has_state_machine/state_helpers_test.rb @@ -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 @@ -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 @@ -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 @@ -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 diff --git a/test/has_state_machine/state_test.rb b/test/has_state_machine/state_test.rb index 33ee988..048d807 100644 --- a/test/has_state_machine/state_test.rb +++ b/test/has_state_machine/state_test.rb @@ -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