diff --git a/lib/workflow.rb b/lib/workflow.rb index f3088ac..0f571dc 100644 --- a/lib/workflow.rb +++ b/lib/workflow.rb @@ -343,7 +343,13 @@ def load_workflow_state # On transition the new workflow state is immediately saved in the # database. def persist_workflow_state(new_value) - update_attribute self.class.workflow_column, new_value + if self.respond_to? :update_column + # Rails 3.1 or newer + update_column self.class.workflow_column, new_value + else + # older Rails; beware of side effect: other (pending) attribute changes will be persisted too + update_attribute self.class.workflow_column, new_value + end end private diff --git a/test/new_versions/persistence_test.rb b/test/new_versions/persistence_test.rb new file mode 100644 index 0000000..b03161a --- /dev/null +++ b/test/new_versions/persistence_test.rb @@ -0,0 +1,62 @@ +require 'test_helper' +require 'active_record' +require 'logger' +require 'sqlite3' +require 'workflow' +require 'mocha/setup' +require 'stringio' + +ActiveRecord::Migration.verbose = false + +class PersistenceTestOrder < ActiveRecord::Base + include Workflow + + workflow do + state :submitted do + event :accept, :transitions_to => :accepted, :meta => {:doc_weight => 8} do |reviewer, args| + end + end + state :accepted do + event :ship, :transitions_to => :shipped + end + state :shipped + end + + attr_accessible :title # protecting all the other attributes + +end + +PersistenceTestOrder.logger = Logger.new(STDOUT) # active_record 2.3 expects a logger instance +PersistenceTestOrder.logger.level = Logger::WARN # switch to Logger::DEBUG to see the SQL statements + +class PersistenceTest < ActiveRecordTestCase + + def setup + super + + ActiveRecord::Schema.define do + create_table :persistence_test_orders do |t| + t.string :title, :null => false + t.string :workflow_state + end + end + + exec "INSERT INTO persistence_test_orders(title, workflow_state) VALUES('order6', 'accepted')" + end + + def assert_state(title, expected_state, klass = PersistenceTestOrder) + o = klass.find_by_title(title) + assert_equal expected_state, o.read_attribute(klass.workflow_column) + o + end + + test 'ensure other dirty attributes are not saved on state change' do + o = assert_state 'order6', 'accepted' + o.title = 'going to change the title' + assert o.changed? + o.ship! + assert o.changed?, 'title should not be saved and the change still stay pending' + end + +end +