Skip to content

Commit

Permalink
Use update_column for newer Rails; ensure other dirty attributes are …
Browse files Browse the repository at this point in the history
…not saved on state change
  • Loading branch information
geekq committed Jan 28, 2013
1 parent f6762b3 commit 7e091d8
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 1 deletion.
8 changes: 7 additions & 1 deletion lib/workflow.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
62 changes: 62 additions & 0 deletions test/new_versions/persistence_test.rb
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 7e091d8

Please sign in to comment.