pluginaweek / state_machine Goto Github PK
View Code? Open in Web Editor NEWAdds support for creating state machines for attributes on any Ruby class
Home Page: http://www.pluginaweek.org
License: MIT License
Adds support for creating state machines for attributes on any Ruby class
Home Page: http://www.pluginaweek.org
License: MIT License
Wojciech Wnętrzak opened this issue
On the rails master branch railtie_name is deprecated. When environment is loaded I get:
DEPRECATION WARNING: railtie_name is deprecated and has no effect. (called from class:Railtie at ~/.rvm/gems/ruby-1.9.1-p378/gems/state_machine-0.9.0/lib/state_machine/initializers/rails.rb:2)
This ticket has 0 attachment(s).
David North opened this issue
I have a Page model record with state ’published’,
@page.state_events => [:draft, :unpublish]
But when I call draft! or unpublish! StateMachine::InvalidTransition is raised. (@page.draft returns false)
"Cannot transition state via :draft from :published"
/event.rb:248:in add_actions’ /machine.rb:512:in
call’
/machine.rb:512:in `draft!’
Version 0.8, Rails 2.3.4
It looks like draft/published is returning false because of my model being invalid so I guess the problem is that this isn’t an appropriate error, its really that it failed to save the change in state, not that the transition was invalid.
Thanks
This ticket has 0 attachment(s).
Aaron Gibralter opened this issue
(commit 883805e)
I was going through and (finally) updating an old model to use the symbol form of states instead of string form and I noticed one issue. I’m not sure if it’s because I’m declaring my events incorrectly, but here it is...
This is my User’s password state_machine:
@@@
state_machine :state_password, :initial => :known, :namespace => :password do
before_transition :to => :forgotten do |user, transition|
user.multipurpose_code = user.new_multipurpose_code
end
before_transition :to => :known do |user, transition|
user.multipurpose_code = nil if user.email_verified?
end
event :forgets do
transition :to => :forgotten, :from => %w(known forgotten)
end
event :remembers do
transition :to => :known, :from => :forgotten
end
end
@@@
I’m having trouble with @user.remembers_password and I’ve traced it back to event.rb:
@@@
def transition_for(object)
from = machine.states.match(object).name
guards.each do |guard|
if match = guard.match(object, :from => from)
# Guard allows for the transition to occur
to = match[:to].values.empty? ? from : match[:to].values.first
return Transition.new(object, machine, name, from, to)
end
end
# No transition matched
nil
end
@@@
(from = machine.states.match(object).name) is returning ’forgotten’ not :forgotten... as a result, guard.match(object, :from => from) is returning nil; however, if I ruby-debug and break on that line and do guard.match(object, :from => from.to_sym) it recognizes it...
Any thoughts? Am I doing something wrong?
Thanks!
-Aaron
This ticket has 0 attachment(s).
Brian Langenfeld opened this issue
Excellent job on this, Aaron.
I’m interested in logging transition results to a log table -- not just successes -- so after_transition isn’t getting the job done. As expected, the log entry gets wiped out upon rollback. I could just turn off transactions for the entire transition, but I’d rather not.
Any plans to include a callback to be executed after a transition transaction ends? I’ve hacked state_machine a bit to tag transitions with the encountered Exception, which is then available to a new after_transaction callback (so you can know if/how the transaction failed)... but maybe you already had something cooking.
If not, let me know... I’d be happy to post a patch, if this sounds like something that fits the direction you want to take with state_machine. Alternatively, if I’m missing something obvious (like an option somewhere), feel free to point it out. I may just be blind.
This ticket has 0 attachment(s).
Aaron Gibralter opened this issue
I committed a bug fix:
http://github.com/agibralter/state_machine/commit/461eae74f7818fd71452761723bd18a58b3a97c4
Basically you just missed changing one instance of "name" to "qualified_name."
-ajg-
This ticket has 0 attachment(s).
Tom opened this issue
I can’t seem to get the state_machine
gem to work on existing records (it works correctly on new records).
Here’s my model:
class Comment < ActiveRecord::Base
state_machine :state, :initial => :pending do
event :publish do
transition all => :published
end
end
end
and here’s an IRB session that demonstrates the issue (I did ActiveRecord::Base.logger = Logger.new(STDOUT)
to make it easier to read):
>> c = Comment.new
=> #<Comment id: nil, song_id: nil, author: nil, body: nil, created_at: nil, updated_at: nil, state: "pending">
>> c.state
=> "pending"
>> c.publish
Comment Create (0.6ms) INSERT INTO "comments" ("updated_at", "body", "author", "song_id", "created_at", "state") VALUES(’2009-11-02 02:44:37’, NULL, NULL, NULL, ’2009-11-02 02:44:37’, ’published’)
=> true
>> Comment.last.state
Comment Load (0.4ms) SELECT * FROM "comments" ORDER BY comments.id DESC LIMIT 1
=> "published"
>> c = Comment.create
Comment Create (0.5ms) INSERT INTO "comments" ("updated_at", "body", "author", "song_id", "created_at", "state") VALUES(’2009-11-02 02:44:47’, NULL, NULL, NULL, ’2009-11-02 02:44:47’, ’pending’)
=> #<Comment id: 4, song_id: nil, author: nil, body: nil, created_at: "2009-11-02 02:44:47", updated_at: "2009-11-02 02:44:47", state: "pending">
>> c.publish
=> true
>> c.save
=> true
>> Comment.last.state
Comment Load (0.4ms) SELECT * FROM "comments" ORDER BY comments.id DESC LIMIT 1
=> "pending"
I.e., everything works fine when I publish
an unsaved comment, but when I try to publish a comment that’s already saved, nothing happens.
Would really appreciate some help here -- I’m literally pulling my hair out (of the left side of my face)!
This ticket has 0 attachment(s).
rbialek (at gmail) opened this issue
The can_event? method returns true even though validations are failing! See the example:
class Att < ActiveRecord::Base
state_machine :status do
state :one do
validate :validation1
end
state :two do
end
event :goto0 do; transition any => :zero ; end
event :goto1 do; transition :zero => :one ; end
event :goto2 do; transition :one => :two ; end
end
def validation1
errors.add_to_base "validation 1 failing"
end
end
a=Att.new :status => "zero"
a.can_goto0? => true
a.can_goto1? => true
a.can_goto2? => false
goto0 and 1 return true because status transition is allowed!
Apparently they do not check the validations so the transition itself fails.
a.goto1 => false
a.errors => @errors={"base"=>["validation 1 failing"]}
Is it intended behavior? Imho the can_goto1? method should return false because we can not do goto1.
Can you fix it or add an example to readme of how to check if the transition is possible with respect to validation?.
Thank you for the great plugin!
++Robert
This ticket has 0 attachment(s).
Aaron Gibralter opened this issue
Does state_machine define methods to test the current state? The github README examples seem to show that vehicle.parked? will say whether or not the vehicle is parked. I’ve been getting kind of unpredictable behavior with my models with multiple state_machines. For some of them the "?" methods work and others don’t:
@@@
state_machine :state_password, :initial => ’known’ do
end
state_machine :state_email, :initial => ’unverified’ do
end
u.known? #=> NoMethodError: undefined method `known?’ for #User:0x3e51a48
@@@
What about creating a method which takes the name of the state_machine as such:
@@@
user.state_password?(’known’) #=> true
user.state_password_known? #=> true
user.state_email?(’verified’) #=> true
user.state_email?(’unverified’) #=> false
@@@
This ticket has 0 attachment(s).
Aaron Gibralter opened this issue
It seems like AR observer callbacks are broken with namespaces... I’ve tracked the problem down to:
lib/state_machine/integrations/active_record.rb:177
@@@
def after_initialize
# Observer callbacks never halt the chain; result is ignored
callbacks[:before] << Callback.new {|object, transition| notify(:before, object, transition)}
callbacks[:after] << Callback.new {|object, transition, result| notify(:after, object, transition)}
end
@@@
lib/state_machine/integrations/active_record.rb:251
@@@
def notify(type, object, transition)
["#{type}_#{transition.event}", "#{type}_transition"].each do |method|
object.class.class_eval do
@observer_peers.dup.each do |observer|
observer.send(method, object, transition) if observer.respond_to?(method)
end if defined?(@observer_peers)
end
end
true
end
@@@
I’m thinking the AR observer should follow the same namespace naming conventions:
@@@
class SomeObserver < ActiveRecord::Observer
def [before/after][event_name][namespace]
# ...
end
end
@@@
So the after_initialize method will have to pass the namespace... I’ll take a stab at the solution.
This ticket has 0 attachment(s).
tsechingho opened this issue
I found the fix [06e8e84]:http://github.com/pluginaweek/state_machine/commit/06e8e845b583fc229ee023dd63abc390e266472e has a syntax error in ruby 1.8.6.
everything works fine in my development box: ruby 1.8.7 (2008-08-11 patchlevel 72) [powerpc-darwin8]
but I got an error in my production box: ruby 1.8.6 (2008-08-11 patchlevel 287) [i686-linux]
@@@
vendor/plugins/state_machine/lib/state_machine/extensions.rb:39: syntax error, unexpected ’,’, expecting ’|’ (SyntaxError)
...e_method(:initialize) {|*args, &block| initialize_with_state...
^
@@@
So I change the line 39 of extensions.rb from
@@@ ruby
define_method(:initialize) {|_args, &block| initialize_with_state_machine(_args, &block) }
@@@
to
@@@ ruby
define_method(:initialize) {|args, block| initialize_with_state_machine(*args, &block) }
@@@
, and it works in both boxes.
This ticket has 0 attachment(s).
qoobaa opened this issue
There’s a problem with using state_event and record serialization:
@@@ ruby
class User < ActiveRecord::Base
state_machine do
event :verify do
transition nil => :verified
end
after_transition :on => :verify do |user|
user.to_yaml
end
end
end
User.create(:state_event => "verify")
@@@
It’s caused because to_yaml is serializing @state_event_transition instance variable (it contains Proc objects). The same problem exists when using Marshal.dump. I’m using serialization to deliver e-mail messages in background.
This ticket has 0 attachment(s).
Wojciech Wnętrzak opened this issue
On the rails master branch railtie_name is deprecated. When environment is loaded I get:
DEPRECATION WARNING: railtie_name is deprecated and has no effect. (called from class:Railtie at ~/.rvm/gems/ruby-1.9.1-p378/gems/state_machine-0.9.0/lib/state_machine/initializers/rails.rb:2)
This ticket has 0 attachment(s).
tsechingho opened this issue
yesterday i check out the new version state machine for my previous project using old version state machine and rails 2.2.2. I encounter two situation which can be produced many times.
(1) /opt/local/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:410: warning: undefining `initialize’ may cause serious problem
I get this waring whether in my previous project or a brand new rails project (rails 2.2.2). The code is as simple as:
@@@ ruby
class User < ActiveRecord::Base
state_machine :initial => ’passive’ do
event :activate do
transition :to => ’active’, :from => ’pending’
end
end
end
@@@
(2) And I can not migrate from the blank database(schema not yet have) in my previous project change to new version state machine. But brand new rails project can do this. I know this maybe is my own problem, but anyone has any suggestion?
@@@
rake db:migrate --trace
rake aborted!
Could not find table ’users’
** Invoke db:migrate (first_time)
** Invoke environment (first_time)
** Execute environment
rake aborted!
Could not find table ’users’
/opt/local/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/connection_adapters/sqlite3_adapter.rb:29:in table_structure’ /opt/local/lib/ruby/gems/1.8/gems/activesupport-2.2.2/lib/active_support/core_ext/object/misc.rb:39:in
returning’
/opt/local/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/connection_adapters/sqlite3_adapter.rb:28:in table_structure’ /opt/local/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/connection_adapters/sqlite_adapter.rb:189:in
columns’
/opt/local/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:1220:in columns’ /opt/local/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:1228:in
columns_hash’
/opt/local/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/attribute_methods.rb:71:in define_attribute_methods’ /Users/tsechingho/Desktop/Facebook/trunk/vendor/plugins/state_machine/lib/state_machine/integrations/active_record.rb:194:in
define_attribute_accessor’
/Users/tsechingho/Desktop/Facebook/trunk/vendor/plugins/state_machine/lib/state_machine/machine.rb:244:in initialize’ /Users/tsechingho/Desktop/Facebook/trunk/vendor/plugins/state_machine/lib/state_machine/machine.rb:184:in
new’
/Users/tsechingho/Desktop/Facebook/trunk/vendor/plugins/state_machine/lib/state_machine/machine.rb:184:in find_or_create’ /Users/tsechingho/Desktop/Facebook/trunk/vendor/plugins/state_machine/lib/state_machine.rb:129:in
state_machine’
/Users/tsechingho/Desktop/Facebook/trunk/lib/authorization/statable_roles.rb:69:in included’ /Users/tsechingho/Desktop/Facebook/trunk/lib/authorization/statable_roles.rb:66:in
class_eval’
/Users/tsechingho/Desktop/Facebook/trunk/lib/authorization/statable_roles.rb:66:in included’ /Users/tsechingho/Desktop/Facebook/trunk/app/models/user.rb:8:in
include’
/Users/tsechingho/Desktop/Facebook/trunk/app/models/user.rb:8
@@@
This ticket has 0 attachment(s).
Aaron Pfeifer opened this issue
When you use a state event and you’ve overridden the event method, the method won’t get called. For example,
class Vehicle < ActiveRecord::Base
state_machine :initial => :parked do
event :ignite do
transition :parked => :idling
end
end
def ignite(*args)
raise ArgumentError # Never gets called
end
end
v = Vehicle.new(:state_event => ’ignite’)
v.save
This transitions the object, but never calls #ignite which is unexpected.
This ticket has 1 attachment(s).
Matt Scilipoti opened this issue
I think ticket #11 corrected this issue if you are using it as a plugin, but not as a gem.
As far as I know, when using it as a gem, we must add entries to our application’s Rakefile. This also required some changes to file organization in state_machine.
I have moved the files and updated the README in http://github.com/mattscilipoti/state_machine/commit/79994017a41922914d42bf5d4202107d93502aee
This ticket has 0 attachment(s).
Nicolas Blanco opened this issue
Hello,
when drawing the following state_machine for a User class, I obtain many ’double’ arrows.
See the drawing included in this ticket.
@@@
state_machine :state, :initial => :pending do
event :subscribe do
transition :pending => :subscribing
end
event :wait_validation do
transition [:subscribing, :refused] => :waiting_validation
end
event :activate do
transition :waiting_validation => :active
end
event :delete do
transition all - :deleted => :deleted
end
event :refuse do
transition :waiting_validation => :refused
end
event :abort do
transition :subscribing => :aborted
end
event :ban do
transition :active => :banned
end
end
@@@
This ticket has 4 attachment(s).
Daniel Neighman opened this issue
Hi,
I updated datamapper to the edge version today for an unrelated reason, and it turns out this breaks state_machine.
I get an exception raised when trying to create a new record, because the state machine is trying to set a property when datamapper has not yet initialized. DataMapper is moving to a state machine to track the dirtiness of an object and the state machine is not yet set when trying to set the property in this method:
https://gist.github.com/08453296ebd63a3bd8dd
In order to use a datamapper object, it’s required that super be called before trying to use any datamapper behavior. If you absolutely have to setup the state machine first, then I think you’d have to talk to dkubb about how this could be dealt with.
I’m sorry I can’t provide more information. This is still a bit in flux if the initialize_state_machines call is required before super.
Cheers
Daniel
This ticket has 0 attachment(s).
Aaron Pfeifer opened this issue
When using event attributes (i.e. the RESTful means of running events), the before callbacks get run twice:
before callbacks should always be called only once during the process.
This ticket has 0 attachment(s).
Aaron Pfeifer opened this issue
As commented on in the blog: event of creation of an object with :initial=>:newly_created state — is it a transition?
I tried:
@@@
before_transition all => :newly_created , :do => :alarm
after_transition all => :newly_created , :do => :alarm
@@@
None was triggered.
Does it mean that initial state has no callbacks? (Workaround would be calling :alarm in object initialize.)
This ticket has 0 attachment(s).
Dennis Theisen opened this issue
Ok, I have a Blog which has Articles which has Comments (all ActiveRecord).
The StateMachine is used in the comments (for moderation/trash/spam states).
When running the following BlogTest, I get a strange exception (at least for me it’s strange):
@@@ ruby
assert Blog.create(:title => ’hey’)
@@@
This is the exception:
@NoMethodError: undefined method `create’ for PluginAWeek::StateMachine::Event:Class
method log in event.rb at line 31
method send in association_collection.rb at line 259
method method_missing in association_collection.rb at line 259
method with_scope in base.rb at line 1841@
The statemachine isn’t used in the Blog at all, only in comments which is a second class child. I also tried to install the @plugin_test_helper@ (which is only needed for running the StateMachineTests themselves anyway, I guess)
Do you have any tip, what I am doing wrong? Or is this really a bug?
This ticket has 0 attachment(s).
Pete Forde opened this issue
I’ve installed the graphviz darwin package, and the graphviz-ruby gem.
I created a very simple class to test the state_machine:draw:rails functionality, and this is what I get:
pete ~/quotesys (edge)$ rake state_machine:draw:rails CLASS=Booking (in /Users/pete/quotesys) SQL (0.4ms) SET SQL_AUTO_IS_NULL=0 SQL (0.6ms) SHOW TABLES SQL (0.2ms) SELECT version FROM schema_migrations Global Columns (3.5ms) SHOW FIELDS FROM `globals` SQL (0.1ms) BEGIN SQL (0.2ms) SELECT count(*) AS count_all FROM `globals` SQL (0.1ms) ROLLBACK Warning: node ’released’, graph ’G’ size too small for label Warning: node ’production’, graph ’G’ size too small for label Warning: node ’installation’, graph ’G’ size too small for label Warning: node ’installed’, graph ’G’ size too small for label Warning: node ’never_booked’, graph ’G’ size too small for label Warning: node ’never_produced’, graph ’G’ size too small for label Warning: node ’never_installed’, graph ’G’ size too small for label Warning: node ’never_removed’, graph ’G’ size too small for label dyld: lazy symbol binding failed: Symbol not found: _pixman_image_create_bits Referenced from: /usr/local/lib/graphviz/libgvplugin_pango.5.dylib Expected in: flat namespace dyld: Symbol not found: _pixman_image_create_bits Referenced from: /usr/local/lib/graphviz/libgvplugin_pango.5.dylib Expected in: flat namespace
This ticket has 5 attachment(s).
Sven Riedel opened this issue
Environment: Rails3 beta3, Ruby 1.9.2
Added "gem ’statemachine’" to my Gemfile, ran "bundle install --relock". Running "rails generate" will then result in:
/home/sr/.bundle/ruby/1.9.1/gems/statemachine-1.0.0/lib/statemachine/action_invokation.rb:58:in `instance_exec’: wrong number of arguments (1 for 0) (ArgumentError)
Tracing the instance_exec calls shows two, with the error generated on the second call:
Sending __instance_exec_82285100_85565950 with #MyApp::Application:0xa396f0c
Sending __instance_exec_82285100_85768070 with #MyApp::Application:0xa396f0c
This ticket has 0 attachment(s).
Aaron Gibralter opened this issue
So it seems like the following code:
@@@
state_machine :state_news, :initial => :unsubscribed, :namespace => :news do
event :toggle do
transition :unsubscribed => :subscribed
transition :subscribed => :unsubscribed
end
end
state_machine :state_standing, :initial => :neutral, :namespace => :standing do
event :toggle do
transition :neutral => :suspended
transition :suspended => :neutral
end
end
@@@
requires the following:
@@@
@user.state_news_event = ’toggle_news’
@user.state_standing_event = ’toggle_standing’
@@@
Should the following be allowed since the first way seems a bit redundant?
@@@
@user.state_news_event = ’toggle’
@user.state_standing_event = ’toggle’
@@@
This ticket has 0 attachment(s).
Paul Strong opened this issue
The state_machine README says that state_machine supports internationalization, but I cannot find any further explanation of how this works. After going through the API I cannot find anyway of doing internationalization of state names short of creating a i18n module from scratch.
Has this feature been implemented yet? I’m sorry if I just overlooked something in the api or docs.
Any pointers or response would be greatly appreciated.
This ticket has 0 attachment(s).
Jonas Grimfelt opened this issue
My ActiveRecord model with migrations OK, and payment_state-value ’unconfirmed’ and handling_state-value ’unconfirmed’ in DB:
@@@ ruby
class Order < ActiveRecord::Base
state_machine :handling_state, :initial => :unconfirmed, :namespace => :handling do
state :unconfirmed
state :new
state :open
state :shipped
state :canceled
event :confirm do
transition :unconfirmed => :new
end
end
state_machine :payment_state, :initial => :unconfirmed, :namespace => :payment do
state :unconfirmed
state :pending
state :charged
state :refunded
event :confirm do
transition :unconfirmed => :pending
end
end
end
@@@
Calls:
@@@ ruby
@order = Order.new
@order.confirm_handling! # ...so far so good, but now:
@order.confirm_payment! # BANG! =(
@@@
Error:
@@@
StateMachine::InvalidTransition: Cannot transition payment_state via :confirm from :unconfirmed
from /opt/local/lib/ruby/gems/1.8/gems/state_machine-0.9.2/lib/state_machine/event.rb:248:in add_actions’ from /opt/local/lib/ruby/gems/1.8/gems/state_machine-0.9.2/lib/state_machine/machine.rb:537:in
call’
from /opt/local/lib/ruby/gems/1.8/gems/state_machine-0.9.2/lib/state_machine/machine.rb:537:in `confirm_payment!’
from (irb):39
from :0
@@@
Calling order.confirm_payment! fails no matter what order I call them in. I’m stuck. =/
This ticket has 0 attachment(s).
Karim Helal opened this issue
Hi all,
I have a model that relies on state_machine to manage its different states. One particular event requires a before_transition as it needs to build a join table fore doing the transition. Unfortunately it doesn’t work.
class DocumentSet < ActiveRecord::Base
state_machine :state, :initial => :draft do
# Callbacks
before_transition :on=>:submit, :do=>:populate_join_table
# States
state :draft
state :submitted
# Events
event :submit do transition :draft=>:submitted, :if=>:can_submit? end
end
def populate_join_table
puts ’::::::::: INSIDE POPULATE_JOIN_TABLE’
end
def can_submit?
raise "Document Set has no Document(s)" if self.document_versions.blank?
true
end
Now when I do DocumentSet.submit, it actually never goes into the populate_join_table as it evaluates the can_submit? as false.
What am I missing?
Thx!
This ticket has 0 attachment(s).
Patrick Klingemann opened this issue
I am having trouble getting my state machine to set the initial state, it was always coming up nil in my staging environment. It works fine in production and development. So I decided to run the tests on state_machine and I’m receiving failures. Is this a configuration issue on my server? Below are the failures:
Failure:
test_should_allow_chaining_scopes(ActiveRecordTest::MachineTest)
[./test/unit/integrations/active_record_test.rb:142:in test_should_allow_chaining_scopes’ /usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in
send’
/usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in `run’]:
<[#<#Class:0x2b7eaef45e40 id: 2, state: nil>]> expected but was
<[]>.
Failure:
test_should_only_include_records_with_state_in_singular_with_scope(ActiveRecordTest::MachineTest)
[./test/unit/integrations/active_record_test.rb:101:in test_should_only_include_records_with_state_in_singular_with_scope’ /usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in
send’
/usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in `run’]:
<[#<#Class:0x2b7eaf11bf80 id: 1, state: nil>]> expected but was
<[]>.
Failure:
test_should_only_include_records_with_states_in_plural_with_scope(ActiveRecordTest::MachineTest)
[./test/unit/integrations/active_record_test.rb:112:in test_should_only_include_records_with_states_in_plural_with_scope’ /usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in
send’
/usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in `run’]:
<[#<#Class:0x2b7eaf0c27f0 id: 1, state: nil>,
#<#Class:0x2b7eaf0c27f0 id: 2, state: nil>]> expected but was
<[]>.
Failure:
test_should_only_include_records_without_state_in_singular_without_scope(ActiveRecordTest::MachineTest)
[./test/unit/integrations/active_record_test.rb:123:in test_should_only_include_records_without_state_in_singular_without_scope’ /usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in
send’
/usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in `run’]:
<[#<#Class:0x2b7eaf03b098 id: 1, state: nil>]> expected but was
<[]>.
Failure:
test_should_only_include_records_without_states_in_plural_without_scope(ActiveRecordTest::MachineTest)
[./test/unit/integrations/active_record_test.rb:135:in test_should_only_include_records_without_states_in_plural_without_scope’ /usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in
send’
/usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in `run’]:
<[#<#Class:0x2b7eaefef710 id: 1, state: nil>,
#<#Class:0x2b7eaefef710 id: 2, state: nil>]> expected but was
<[]>.
Failure:
test_should_use_machine_default(ActiveRecordTest::MachineWithColumnDefaultTest)
[./test/unit/integrations/active_record_test.rb:369:in test_should_use_machine_default’ /usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in
send’
/usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in `run’]:
<"parked"> expected but was
<"idling">.
Failure:
test_should_return_true_for_predicate_if_matches_current_value(ActiveRecordTest::MachineWithColumnStateAttributeTest)
[./test/unit/integrations/active_record_test.rb:415:in test_should_return_true_for_predicate_if_matches_current_value’ /usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in
send’
/usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in `run’]:
is not true.
Failure:
test_should_test_for_existence_on_predicate_without_parameters(ActiveRecordTest::MachineWithColumnStateAttributeTest)
[./test/unit/integrations/active_record_test.rb:404:in test_should_test_for_existence_on_predicate_without_parameters’ /usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in
send’
/usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in `run’]:
is not true.
Failure:
test_should_not_set_initial_state_after_already_initialized(ActiveRecordTest::MachineWithDynamicInitialStateTest)
[./test/unit/integrations/active_record_test.rb:351:in test_should_not_set_initial_state_after_already_initialized’ /usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in
send’
/usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in `run’]:
<"parked"> expected but was
.
Failure:
test_should_set_attributes_prior_to_after_initialize_hook(ActiveRecordTest::MachineWithDynamicInitialStateTest)
[./test/unit/integrations/active_record_test.rb:333:in test_should_set_attributes_prior_to_after_initialize_hook’ /usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in
send’
/usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in `run’]:
<"parked"> expected but was
.
Failure:
test_should_set_initial_state_after_setting_attributes(ActiveRecordTest::MachineWithDynamicInitialStateTest)
[./test/unit/integrations/active_record_test.rb:346:in test_should_set_initial_state_after_setting_attributes’ /usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in
send’
/usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in `run’]:
<"nil"> expected but was
.
Failure:
test_should_set_initial_state_on_created_object(ActiveRecordTest::MachineWithDynamicInitialStateTest)
[./test/unit/integrations/active_record_test.rb:308:in test_should_set_initial_state_on_created_object’ /usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in
send’
/usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in `run’]:
<"parked"> expected but was
.
Failure:
test_should_still_set_attributes(ActiveRecordTest::MachineWithDynamicInitialStateTest)
[./test/unit/integrations/active_record_test.rb:313:in test_should_still_set_attributes’ /usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in
send’
/usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in `run’]:
<1> expected but was
.
Failure:
test_should_not_change_current_state(ActiveRecordTest::MachineWithFailedActionTest)
[./test/unit/integrations/active_record_test.rb:806:in test_should_not_change_current_state’ /usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in
send’
/usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in `run’]:
<"parked"> expected but was
.
Failure:
test_should_not_change_current_state(ActiveRecordTest::MachineWithFailedBeforeCallbacksTest)
[./test/unit/integrations/active_record_test.rb:763:in test_should_not_change_current_state’ /usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in
send’
/usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in `run’]:
<"parked"> expected but was
.
Failure:
test_should_allow_different_initial_state_when_dynamic(ActiveRecordTest::MachineWithInitializedStateTest)
[./test/unit/integrations/active_record_test.rb:584:in test_should_allow_different_initial_state_when_dynamic’ /usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in
send’
/usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in `run’]:
<"idling"> expected but was
.
Failure:
test_should_allow_different_initial_state_when_static(ActiveRecordTest::MachineWithInitializedStateTest)
[./test/unit/integrations/active_record_test.rb:578:in test_should_allow_different_initial_state_when_static’ /usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in
send’
/usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in `run’]:
<"idling"> expected but was
.
Failure:
test_should_use_default_state_if_protected(ActiveRecordTest::MachineWithInitializedStateTest)
[./test/unit/integrations/active_record_test.rb:593:in test_should_use_default_state_if_protected’ /usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in
send’
/usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in `run’]:
<"parked"> expected but was
.
Error:
test_should_include_state_in_changed_attributes(ActiveRecordTest::MachineWithLoopbackTest):
NoMethodError: undefined method delete’ for nil:NilClass ./test/unit/integrations/active_record_test.rb:729:in
test_should_include_state_in_changed_attributes’
/usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in __send__’ /usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in
run’
Failure:
test_should_return_true_for_predicate_if_matches_current_value(ActiveRecordTest::MachineWithNonColumnStateAttributeDefinedTest)
[./test/unit/integrations/active_record_test.rb:474:in test_should_return_true_for_predicate_if_matches_current_value’ /usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in
send’
/usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in `run’]:
is not true.
Failure:
test_should_set_initial_state_on_created_object(ActiveRecordTest::MachineWithNonColumnStateAttributeDefinedTest)
[./test/unit/integrations/active_record_test.rb:482:in test_should_set_initial_state_on_created_object’ /usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in
send’
/usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in `run’]:
<"parked"> expected but was
.
Failure:
test_should_only_include_records_with_subclass_states_in_with_scope(ActiveRecordTest::MachineWithOwnerSubclassTest)
[./test/unit/integrations/active_record_test.rb:515:in test_should_only_include_records_with_subclass_states_in_with_scope’ /usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in
send’
/usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in `run’]:
<[#<#Class:0x2b7eaec67840 id: 1, state: nil>,
#<#Class:0x2b7eaec67840 id: 2, state: nil>]> expected but was
<[]>.
Failure:
test_should_only_include_records_without_subclass_states_in_without_scope(ActiveRecordTest::MachineWithOwnerSubclassTest)
[./test/unit/integrations/active_record_test.rb:523:in test_should_only_include_records_without_subclass_states_in_without_scope’ /usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in
send’
/usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in `run’]:
<[#<#Class:0x2b7eaf20cb88 id: 1, state: nil>,
#<#Class:0x2b7eaf20cb88 id: 2, state: nil>]> expected but was
<[]>.
Failure:
test_should_be_invalid_if_validation_fails_within_state_scope(ActiveRecordTest::MachineWithStateDrivenValidationsTest)
[./test/unit/integrations/active_record_test.rb:869:in test_should_be_invalid_if_validation_fails_within_state_scope’ /usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in
send’
/usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in `run’]:
is not true.
Failure:
test_should_not_set_initial_state_after_already_initialized(ActiveRecordTest::MachineWithStaticInitialStateTest)
[./test/unit/integrations/active_record_test.rb:289:in test_should_not_set_initial_state_after_already_initialized’ /usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in
send’
/usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in `run’]:
<"parked"> expected but was
.
Failure:
test_should_set_attributes_prior_to_after_initialize_hook(ActiveRecordTest::MachineWithStaticInitialStateTest)
[./test/unit/integrations/active_record_test.rb:271:in test_should_set_attributes_prior_to_after_initialize_hook’ /usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in
send’
/usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in `run’]:
<"parked"> expected but was
.
Failure:
test_should_set_initial_state_before_setting_attributes(ActiveRecordTest::MachineWithStaticInitialStateTest)
[./test/unit/integrations/active_record_test.rb:284:in test_should_set_initial_state_before_setting_attributes’ /usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in
send’
/usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in `run’]:
<"parked"> expected but was
.
Failure:
test_should_set_initial_state_on_created_object(ActiveRecordTest::MachineWithStaticInitialStateTest)
[./test/unit/integrations/active_record_test.rb:241:in test_should_set_initial_state_on_created_object’ /usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in
send’
/usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in `run’]:
<"parked"> expected but was
.
Failure:
test_should_set_initial_state_with_nil_attributes(ActiveRecordTest::MachineWithStaticInitialStateTest)
[./test/unit/integrations/active_record_test.rb:246:in test_should_set_initial_state_with_nil_attributes’ /usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in
send’
/usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in `run’]:
<"parked"> expected but was
.
Failure:
test_should_still_set_attributes(ActiveRecordTest::MachineWithStaticInitialStateTest)
[./test/unit/integrations/active_record_test.rb:251:in test_should_still_set_attributes’ /usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in
send’
/usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/testing/setup_and_teardown.rb:62:in `run’]:
<1> expected but was
.
This ticket has 0 attachment(s).
Jérémy Lecour opened this issue
Hi,
I’ve cloned state_machine and launched the test suite for ActiveRecord.
I have a Rails 2.3.x setup but the latest I18n gem.
The test suite gives me some warning about the interpolation key format, saying it’s deprecated.
I’ve looked in the source and it appears that you check the major version number for ActiveRecord to see if it’s Rails 2 or 3.
In fact I think that you should check for the version of the I18n gem instead, since it seems that it’s responsible for this API change.
I’m sorry not to provide any patch.
Thanks for state_machine. I’ve not yet really used it but it seems to be a very good piece of code ;-)
This ticket has 0 attachment(s).
Piotr Usewicz opened this issue
Therefore, it breaks eg rake -T in merb.
This ticket has 0 attachment(s).
state_machine is a great plugin but I've found a problem.
When you add a state_machine to an existing ActiveRecord model and load an existing model, the state of the model is therefore nil, state_machine raises an exception when you call an event.
>> u = User.last => # >> u.state => nil >> u.activate! NoMethodError: You have a nil object when you didn't expect it! The error occurred while evaluating nil.name from /Library/Ruby/Gems/1.8/gems/pluginaweek-state_machine-0.7.6/lib/state_machine/event.rb:166:in `transition_for' from /Library/Ruby/Gems/1.8/gems/pluginaweek-state_machine-0.7.6/lib/state_machine/event.rb:190:in `fire' from /Library/Ruby/Gems/1.8/gems/pluginaweek-state_machine-0.7.6/lib/state_machine/event.rb:242:in `add_actions' from /Library/Ruby/Gems/1.8/gems/pluginaweek-state_machine-0.7.6/lib/state_machine/machine.rb:512:in `call' from /Library/Ruby/Gems/1.8/gems/pluginaweek-state_machine-0.7.6/lib/state_machine/machine.rb:512:in `activate' from /Library/Ruby/Gems/1.8/gems/pluginaweek-state_machine-0.7.6/lib/state_machine/event.rb:247:in `send' from /Library/Ruby/Gems/1.8/gems/pluginaweek-state_machine-0.7.6/lib/state_machine/event.rb:247:in `add_actions' from /Library/Ruby/Gems/1.8/gems/pluginaweek-state_machine-0.7.6/lib/state_machine/machine.rb:512:in `call' from /Library/Ruby/Gems/1.8/gems/pluginaweek-state_machine-0.7.6/lib/state_machine/machine.rb:512:in `activate!' from (irb):3
Patrick Klingemann opened this issue
Aaron,
Thanks for your great work on this plugin/gem, it is quite useful to me. I am building a workflow form with state machine in which the form that is displayed is based on the state of a state machine. The issue I’m having is that I need to validate certain fields based on the state that the state machine is in currently, and state_machine’s behavior validates fields based on the state to which the state machine is transitioning.
I am wondering if this has been considered as an option, also I would be glad to help develop an option to accomplish this. You may a have a strong opinion against this, but otherwise, could you provide me some guidelines on how I might tackle this issue? I am using ActiveRecord with Rails 2.3.2.
Once again, thanks for your contributions to the community.
Patrick Klingemann
This ticket has 0 attachment(s).
Jon opened this issue
I noticed an error in the API that may confuse some people.
@@@ ruby
state_machine :state, :initial => ’idling’ do
end
@@@
Yet, the example shows the initial state to be ’parked’.
@@@ ruby
vehicle = Vehicle.create # => #<Vehicle id: 1, seatbelt_on: false, state: "parked">
@@@
Thanks for the plugin!
This ticket has 0 attachment(s).
Philippe Creux opened this issue
Hey,
I’m looking for a good practice to transition to two different states depending on the success or failure of an event?
For example, I want the following:
BalanceTransfer.create
=> <BalanceTransfer, @state => :new >
# on success
BalanceTransfer.create.perform_transfer
=> <BalanceTransfer, @state => :completed >
# on failure
BalanceTransfer.create.perform_transfer
=> <BalanceTransfer, @state => :error >
So far, I’ve done that using a method ’perform_transfer’:
def perform_transfer
return unless self.state == :new
# perform the transfer...
if success
complete!
else
error!
end
end
It looks like re-inventing the wheel and it’s quite ugly. Am I missing a feature built it state_machine? Is there any good pratice for doing such a thing?
Thanks!
This ticket has 0 attachment(s).
I have come across some serious issues with using the no-peeping-toms plugin along with the state machine plugin. If you have any state machine configured in any loaded file, then the no-peeping system breaks, and also the specs fail. I am working on a solution to this but wanted to note it on both repositories. Perhaps someone else may come up with a fix first.
Colin Gemmell opened this issue
Hi there
I was using state machine and was trying to modify the error messages to be more useful to our users. As per the documentation I added this to the en.yml file
en:
activerecord:
errors:
messages:
invalid: "you request is invalid"
invalid_event: "please choose an option below"
invalid_transition: "that option is not available here"
However this made no change to the output. On further investigation I found that state-machines defaults where being added last to the I18n.load_path causing them to overwrite my customisations.
removing the line in integrations/active_record.rb fixed the problem as defaults where not being added
I18n.load_path << locale unless I18n.load_path.include?(locale)
Cheers
Colin G
This ticket has 0 attachment(s).
Aaron Gibralter opened this issue
Have you ever thought of creating a standardized collection of state_machines that represents best practices for user-group membership related states?
I have a pretty complicated set of state_machines that represents a user being invited to a group (based roughly on, say, facebook’s group invite system):
@@@
state_machine :state_user, :initial => :pending, :namespace => :by_user do
before_transition :to => :accepted do |membership|
membership.activate(false)
true
end
before_transition :to => :suspended do |membership|
membership.deactivate(false)
true
end
before_transition :from => :suspended do |membership|
membership.activate(false)
true
end
event :request do
transition :to => :requested, :from => :pending, :if => lambda { |membership| membership.by_admin_pending? }
transition :to => :accepted, :from => [:pending, :rejected, :suspended], :if => lambda { |membership| membership.by_admin_requested? }
transition :to => :requested, :from => :suspended, :if => lambda { |membership| membership.by_admin_accepted? }
end
event :cancel do
transition :to => :pending, :from => :requested, :if => lambda { |membership| membership.by_admin_pending? }
end
event :reject do
transition :to => :rejected, :from => :pending, :if => lambda { |membership| membership.by_admin_requested? }
end
event :suspend do
transition :to => :suspended, :from => [:accepted, :requested], :if => lambda { |membership| !membership.admin? || membership.group.admins.size > 1 }
end
end
state_machine :state_admin, :initial => :pending, :namespace => :by_admin do
before_transition :to => :accepted do |membership|
membership.activate(false)
true
end
before_transition :to => :suspended do |membership|
membership.deactivate(false)
true
end
before_transition :from => :suspended do |membership|
membership.activate(false)
true
end
event :pre_accept do
transition :to => :accepted, :from => :pending
end
event :request do
transition :to => :requested, :from => :pending, :if => lambda { |membership| membership.by_user_pending? }
transition :to => :accepted, :from => [:pending, :rejected, :suspended], :if => lambda { |membership| membership.by_user_requested? }
transition :to => :requested, :from => :suspended, :if => lambda { |membership| membership.by_user_accepted? }
end
event :cancel do
transition :to => :pending, :from => :requested, :if => lambda { |membership| membership.by_user_pending? }
end
event :reject do
transition :to => :rejected, :from => :pending, :if => lambda { |membership| membership.by_user_requested? }
end
event :suspend do
transition :to => :suspended, :from => [:accepted, :requested], :if => lambda { |membership| !membership.admin? }
end
end
@@@
This leads to the following full/combined states:
@@@
def full_state
case [state_user, state_admin]
when %w(pending pending)
:nothing
when %w(pending requested)
:requested_by_admin
when %w(requested pending)
:requested_by_user
when %w(requested accepted)
:member
when %w(requested rejected)
:rejected_by_admin
when %w(requested suspended)
:suspended_by_admin
when %w(accepted requested)
:member
when %w(accepted suspended)
:suspended_by_admin
when %w(rejected requested)
:rejected_by_user
when %w(suspended requested)
:suspended_by_user
when %w(suspended accepted)
:suspended_by_user
else
raise UnanticipatedState
end
end
@@@
This is /really/ hackish and cumbersome though... any thoughts?
I just thought it might help in terms of making state_machine the ubiquitous solution for ruby state handling by providing a plug-n-play solution for web app developers.
Thanks for the shout-out in the blog post btw (http://www.pluginaweek.org/2009/03/08/state_machine-one-machine-to-rule-them-all/)!
This ticket has 0 attachment(s).
Aaron Gibralter opened this issue
Ok so here’s what I’ve got working... I added this to the StateMachine::Machine class:
@@@
def define_state_transitions(*states)
states_hash = {}
if states.last.is_a?(Hash)
states.last.each { |state, message| states_hash[state.to_sym] = message }
else
states.each { |state| states_hash[state.to_sym] = state.to_sym }
end
event_names = {}
loops = []
states_hash.keys.each do |state_from|
event_names[state_from] = {}
states_hash.keys.each do |state_to|
event = event("#{state_from}__to__#{state_to}") do
transition :to => state_to, :from => state_from
end
event_names[state_from][state_to] = event.qualified_name
loops << event.qualified_name if state_to == state_from
end
end
event_attr_name = self.namespace ? :"#{self.namespace}_state_transition" : :state_transition
current_attribute = self.attribute
@instance_helper_module.class_eval do
define_method(event_attr_name) do
current_state = self.send(current_attribute).to_sym
states_hash.keys.include?(current_state) ? event_names[current_state][current_state] : nil
end
end
@instance_helper_module.class_eval do
define_method("#{event_attr_name}s") do
current_state = self.send(current_attribute).to_sym
states_hash.keys.include?(current_state) ? states_hash.keys.collect { |state| [states_hash[state], event_names[current_state][state]] } : []
end
end
owner_class.class_eval do
validate do |model|
model.errors.add(event_attr_name, "invalid selection") if model.instance_variable_get("@#{event_attr_name}") == :invalid
end
end
@instance_helper_module.class_eval do
define_method("#{event_attr_name}=") do |event_name|
current_state = self.send(current_attribute).to_sym
event_name = event_name.to_sym
unless event_names[current_state].values.include?(event_name) && (loops.include?(event_name) || self.send(event_name, false))
instance_variable_set("@#{event_attr_name}", :invalid)
end
end
end
end
@@@
This is clearly a really bloated method and could probably be abstracted into a separate class. Also, the validation need to be in the integration because it is AR specific.
Anyway...
What this allows you to do is something like this:
@@@
class Post < ActiveRecord::Base
state_machine :state_visibility, :initial => :public, :namespace => :visible do
define_state_transitions :public => ’make public’, :private => ’for your eyes only’
end
end
@post = Post.new
@post.state_visibility #=> :public
@post.visible_state_transitions = [[’make public’, :public__to__public_visible], [’for your eyes only’, :public__to__private_visible]]
@post.update_attributes(:visible_state_transition => ’public__to__public_visible’) # essentially a no-op
@post.valid? #=> true
@post.visible_public? #=> true
@post.visible_private? #=> false
@post.update_attributes(:visible_state_transition => ’public__to__private_visible’)
@post.valid? #=> true
@post.visible_public? #=> false
@post.visible_private? #=> true
@post.visible_state_transitions = [[’make public’, :private__to__public_visible], [’for your eyes only’, :private__to__private_visible]]
@post.update_attributes(:visible_state_transition => ’private__to__private_visible’) # essentially a no-op
@post.valid? #=> true
@post.visible_public? #=> false
@post.visible_private? #=> true
@post.update_attributes(:visible_state_transition => ’public__to__public_visible’)
@post.valid? #=> false! invalid transition because the ’start’ position is private
@post.visible_public? #=> false
@post.visible_private? #=> true
@@@
Any thoughts?
This ticket has 1 attachment(s).
Aaron Gibralter opened this issue
Ok, so I can’t really figure out what’s going on here. For some reason it seems like the columns associated with state_machine in my migrations are always being set blank.
Here is a link to part of my migration and two of my models:
https://gist.github.com/d079cdfedb66dff9361f
After the migration, the every row in the contextualizations table has state_status_admin and state_status_user blank (even though they are NOT NULL columns!)...
However, when I go into script/console and issue a very similar command to what is in my migration, it works just fine! At first I thought it was because I was running a bunch of migrations at once and forgot reset_column_information... but adding that didn’t do the trick.
Any thoughts??
Many thanks in advance!
This ticket has 0 attachment(s).
Kane opened this issue
when defineing a method like
@@@ ruby
state_machine :state, :initial => :applicating do
state :applicating do
def fame_buy_in=(value)
write_attribute(:fame_buy_in, value)
end
end
end
@@@
an ArgumentError is thrown while trying to create a new object with .new(:fame_buy_in=>12)
ArgumentError: nil is not a known state value
E:/DEV/ruby/lib/ruby/gems/1.8/gems/pluginaweek-state_machine-0.7.6/lib/state_machine/state_collection.rb:80:in match!’ E:/DEV/ruby/lib/ruby/gems/1.8/gems/pluginaweek-state_machine-0.7.6/lib/state_machine/state.rb:170:in
fame_buy_in=’
E:/DEV/ruby/lib/ruby/gems/1.8/gems/pluginaweek-state_machine-0.7.6/lib/state_machine/extensions.rb:30:in `initialize
This ticket has 0 attachment(s).
Pete Forde opened this issue
I noticed that there’s no tasks folder in state_machine. The way rake works (as I understand it) is that any rake tasks in files with a .rake extension in a tasks folder will show up in the available tasks for a project.
In my local checkout I:
mkdir tasks
cp Rakefile tasks/Rakefile.rake
And that works. I’m sure there’s a best practice I’m probably missing, but I hope this helps.
This ticket has 0 attachment(s).
Pete Forde opened this issue
Hey Aaron,
I’m sorry that what I’m about to say isn’t tested or particularly demonstrable, but in certain places in my app I seem to run into situations (under 2.2.2) where for some reason state_machine explodes and the whole mongrel instance needs to be restarted.
Here’s an example:
class User < ActiveRecord::Base state_machine :initial => :pending do event :activate do transition :from => :pending, :to => :active end event :reactivate do transition :from => :disabled, :to => :active end event :disable do transition :from => :active, :to => :disabled end end end
In this situation where the problem occurs, it bombs with a really long error stack:
wrong number of arguments (0 for 2) vendor/plugins/state_machine/lib/state_machine/machine.rb:1020:in `pluralize’ vendor/plugins/state_machine/lib/state_machine/machine.rb:1020:in `define_scopes’ vendor/plugins/state_machine/lib/state_machine/machine.rb:265:in `initialize’ vendor/plugins/state_machine/lib/state_machine/machine.rb:171:in `new’ vendor/plugins/state_machine/lib/state_machine/machine.rb:171:in `find_or_create’ vendor/plugins/state_machine/lib/state_machine.rb:309:in `state_machine’ app/models/user.rb:27
Just to explain, line 27 of the User model is where I call state_machine.
After testing, I concluded that if on machine.rb line 1020 attribute is a Symbol, for some reason responds_to? returns true and it blows up.
Strangely, if I modify the call like so:
attributes.pluralize(2, ’girl’) # => plural is girls
Anyhow, I tweaked my local plugin source so it looked more like this:
plural = custom_plural || (attribute.respond_to?(:pluralize) ? attribute.to_s.pluralize : "#{attribute}s")
And it works!
For some reason, sometimes attribute is a Symbol, which doesn’t have a pluralize method. That said, I have no idea why attribute.respond_to? returns true in this case.
Hope this helps.
This ticket has 0 attachment(s).
Aaron Gibralter opened this issue
I’ve encountered a few cases where I might want to call a transition without immediately saving the record.
For instance, on line 166 of user.rb (http://gist.github.com/16815) in one of my before_save callbacks, I want to transition to an "unverified" email. I don’t want to save in my before_save callback though... Also on lines 105 and 106 of user.rb, I want to make a few transitions at once. It seems wasteful to make 3 save calls in a row.
Anyway, does anyone have thoughts on this commit which adds the ability to call any event without saving? I do it by allowing events to be called with a "false" argument.
http://github.com/agibralter/state_machine/commit/c588b743763921ab9d60999cc2878d93544db492
P.S. I did encounter a few bugs in my UserObserver code as a result of this changeset... As you can see in user_observer.rb (http://gist.github.com/16815), it is possible for my after_unverify callback to get called before the user has been saved... as a result user doesn’t have an id yet. I don’t think this is a fault of my commit though, more a fault of my callback design.
This ticket has 0 attachment(s).
Thomas Darde opened this issue
I think the state_events helper is not generated when using multiple state_machines and the namespace feature. (only the main namespace is available)
This ticket has 0 attachment(s).
Nicolas Blanco opened this issue
state_machine is a great plugin but I’ve found a problem.
When you add a state_machine to an existing ActiveRecord model and load an existing model, the state of the model is therefore nil, state_machine raises an exception when you call an event.
@@@
u = User.last
=> #
u.state
=> nil
u.activate!
NoMethodError: You have a nil object when you didn’t expect it!
The error occurred while evaluating nil.name
from /Library/Ruby/Gems/1.8/gems/pluginaweek-state_machine-0.7.6/lib/state_machine/event.rb:166:intransition_for’ from /Library/Ruby/Gems/1.8/gems/pluginaweek-state_machine-0.7.6/lib/state_machine/event.rb:190:in
fire’
from /Library/Ruby/Gems/1.8/gems/pluginaweek-state_machine-0.7.6/lib/state_machine/event.rb:242:inadd_actions’ from /Library/Ruby/Gems/1.8/gems/pluginaweek-state_machine-0.7.6/lib/state_machine/machine.rb:512:in
call’
from /Library/Ruby/Gems/1.8/gems/pluginaweek-state_machine-0.7.6/lib/state_machine/machine.rb:512:inactivate’ from /Library/Ruby/Gems/1.8/gems/pluginaweek-state_machine-0.7.6/lib/state_machine/event.rb:247:in
send’
from /Library/Ruby/Gems/1.8/gems/pluginaweek-state_machine-0.7.6/lib/state_machine/event.rb:247:inadd_actions’ from /Library/Ruby/Gems/1.8/gems/pluginaweek-state_machine-0.7.6/lib/state_machine/machine.rb:512:in
call’
from /Library/Ruby/Gems/1.8/gems/pluginaweek-state_machine-0.7.6/lib/state_machine/machine.rb:512:in `activate!’
from (irb):3
@@@
This ticket has 0 attachment(s).
Aaron Gibralter opened this issue
commit 6f25124
When I do User.new my state_email is "" not "fresh"
Any thoughts?
This ticket has 0 attachment(s).
germaninthetown opened this issue
Before all, thank you Aaron for this great gem. It’s amazing.
However I got an error while using it in my rails 2.1 application (yes, I know, it’s old).
$ rails -v
Rails 2.1.0
$ ruby -v
ruby 1.8.6 (2008-08-08 patchlevel 286) [i686-linux]
I have a model Cart
class Cart < ActiveRecord::Base
...
state_machine :fullfilment_status, :initial => :incomplete do
state :waiting_for_cutout_processing, :value => "Waiting for Manual Cutout Processing"
state :processing, :value => "Cutouts being Processed"
state :waiting_for_customer_approval, :value => "Waiting for Customer Approval"
state :ready_to_print, :value => "Ready to Print"
state :being_printed, :value => "Being Printed"
state :shipped, :value => "Shipped"
state :cancelled, :value => "Cancelled"
state :incomplete, :value => "incomplete"
state :reclamation, :value => "Reclamation - being reprinted"
event :purchase do
transition :incomplete => :waiting_for_cutout_processing
end
event :wait_for_approval do
transition :waiting_for_cutout_processing => :waiting_for_customer_approval
end
event :process do
transition :waiting_for_cutout_processing => :processing, :waiting_for_customer_approval => :processing
end
event :cancel do
transition all => :cancelled
end
event :ship do
transition :processed => :shipped
end
event :print do
transition :ready_to_print => :processing
end
event :reclaim do
transition :shipped => :being_printed
end
end
...
end
but when I got to the ./script/console I got the error:
=> Cart.last
NameError: uninitialized constant ActiveRecord::VERSION
from /home/german/.gem/ruby/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:278:in load_missing_constant’ from /home/german/.gem/ruby/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:467:in
const_missing’
from /opt/ruby-enterprise-1.8.6-20090201/lib/ruby/gems/1.8/gems/state_machine-0.9.0/lib/state_machine/integrations/active_record.rb:468:in define_scope’ from /opt/ruby-enterprise-1.8.6-20090201/lib/ruby/gems/1.8/gems/state_machine-0.9.0/lib/state_machine/integrations/active_record.rb:446:in
create_with_scope’
from /opt/ruby-enterprise-1.8.6-20090201/lib/ruby/gems/1.8/gems/state_machine-0.9.0/lib/state_machine/machine.rb:1523:in send’ from /opt/ruby-enterprise-1.8.6-20090201/lib/ruby/gems/1.8/gems/state_machine-0.9.0/lib/state_machine/machine.rb:1523:in
define_scopes’
from /opt/ruby-enterprise-1.8.6-20090201/lib/ruby/gems/1.8/gems/state_machine-0.9.0/lib/state_machine/machine.rb:1520:in each’ from /opt/ruby-enterprise-1.8.6-20090201/lib/ruby/gems/1.8/gems/state_machine-0.9.0/lib/state_machine/machine.rb:1520:in
define_scopes’
from /opt/ruby-enterprise-1.8.6-20090201/lib/ruby/gems/1.8/gems/state_machine-0.9.0/lib/state_machine/machine.rb:1519:in each’ from /opt/ruby-enterprise-1.8.6-20090201/lib/ruby/gems/1.8/gems/state_machine-0.9.0/lib/state_machine/machine.rb:1519:in
define_scopes’
from /opt/ruby-enterprise-1.8.6-20090201/lib/ruby/gems/1.8/gems/state_machine-0.9.0/lib/state_machine/machine.rb:445:in initialize’ from /opt/ruby-enterprise-1.8.6-20090201/lib/ruby/gems/1.8/gems/state_machine-0.9.0/lib/state_machine/machine.rb:332:in
new’
from /opt/ruby-enterprise-1.8.6-20090201/lib/ruby/gems/1.8/gems/state_machine-0.9.0/lib/state_machine/machine.rb:332:in find_or_create’ from /opt/ruby-enterprise-1.8.6-20090201/lib/ruby/gems/1.8/gems/state_machine-0.9.0/lib/state_machine.rb:378:in
state_machine’
from /home/german/projects/ltlprints/app/models/cart.rb:11
from /home/german/.gem/ruby/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:215:in load_without_new_constant_marking’ from /home/german/.gem/ruby/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:215:in
load_file’
from /home/german/.gem/ruby/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:354:in new_constants_in’ from /home/german/.gem/ruby/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:214:in
load_file’
from /home/german/.gem/ruby/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:95:in require_or_load’ from /home/german/.gem/ruby/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:260:in
load_missing_constant’
from /home/german/.gem/ruby/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:467:in const_missing’ from /home/german/.gem/ruby/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:479:in
const_missing’
from (irb):1>>
I tried to find the error and finally got the code working by adding the following line
require ’active_record/version’
to the method self.extended (line 325) in /state_machine-0.9.0/lib/state_machine/integrations/active_record.rb file.
I’m not quite sure is this error appearing for me only, or I just did something wrong elsewhere in the code, but I think it would be great, if you’ll add this line to your code so other developers wouldn’t notice this error in future. How do you think?
Thanks,
Dmitrii Samoilov.
This ticket has 0 attachment(s).
qoobaa opened this issue
@@@ ruby
state_machine :initial => :first do
event :boom
transition :first => :second
end
state :second
validate :something # validation fails
end
after_transition :boom, :do => lambda { puts "BOOM!!!" }
@@@
result:
@@@
object_with_state_machine.boom!
BOOM!!!
StateMachine::InvalidTransition: Cannot transition state via :boom from :first
@@@
I think it’s not expected behavior, it causes a lot of problems in my app.
This ticket has 0 attachment(s).
dan morris opened this issue
Any idea why i’m getting this error?
undefined method `state_machine’
I’ve installed the 0.9.2 gem in a Rails beta 3 app.
I’ve tried a few things and got a different problem before where transitioning wouldn’t work at all.
Many thanks!
This ticket has 0 attachment(s).
onitony opened this issue
It seems that if a State Machine instance performs a transition that loops back into it’s previous state, the record is not saved (because no fields have been modified?). The desired behaviour though, is for updated_at to update, to note the time the transition took place (same as it happens in non-loopback transitions).
This ticket has 1 attachment(s).
qoobaa opened this issue
I’ve got following user model:
@@@ ruby
class User < ActiveRecord::Base
state_machine do
event :event_one do
transition nil => :state_one
end
after_transition :on => :event_one, :do => :something
end
def something
throw :something
end
end
@@@
When I create model with state_event, it doesn’t call "something" method. When I use transaction method (user.event_one) everything works fine.
@@@ ruby
user = User.new(:state_event => "event_one")
user.save
user.state_one?
user = User.new
user.event_one
@@@
This ticket has 1 attachment(s).
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.