Joshua Muheim
2009-Apr-20 20:24 UTC
acts_as_state_machine: bug?! obj.save doesn''t work...
Hi all I''m trying to understand, what acts_as_state_machine really does (I use it because restful_authentication uses it). restful_authentication defines the following stuff: acts_as_state_machine :initial => :pending state :passive state :pending, :enter => :make_activation_code state :active, :enter => :do_activate state :suspended state :deleted, :enter => :do_delete event :register do transitions :from => :passive, :to => :pending, :guard => Proc.new {|u| !(u.crypted_password.blank? && u.password.blank?) } end event :activate do transitions :from => :pending, :to => :active end event :suspend do transitions :from => [:passive, :pending, :active], :to => :suspended end event :delete do transitions :from => [:passive, :pending, :active, :suspended], :to => :deleted end event :unsuspend do transitions :from => :suspended, :to => :active, :guard => Proc.new {|u| !u.activated_at.blank? } transitions :from => :suspended, :to => :pending, :guard => Proc.new {|u| !u.activation_code.blank? } transitions :from => :suspended, :to => :passive end I played a bit with the console... josh$ script/console Loading development environment (Rails 2.1.0)>> record = User.new({ :login => ''quire'', :email => ''quire-hcDgGtZH8xNBDgjK7y7TUQ@public.gmane.org'', :password => ''quire'', :password_confirmation => ''quire'' })=> #<User id: nil, first_name: nil, last_name: nil, login: "quire", email: "quire-hcDgGtZH8xNBDgjK7y7TUQ@public.gmane.org", remember_token: nil, crypted_password: nil, password_reset_code: nil, salt: nil, activation_code: nil, remember_token_expires_at: nil, activated_at: nil, deleted_at: nil, state: "passive", created_at: nil, updated_at: nil> Why is the state "passive"? Is the state of an unsaved object always "passive"?>> record.save=> true>> record=> #<User id: 4, first_name: nil, last_name: nil, login: "quire", email: "quire-hcDgGtZH8xNBDgjK7y7TUQ@public.gmane.org", remember_token: nil, crypted_password: "5670fb5c84b89d64ef405b315e4337304f88dc2b", password_reset_code: nil, salt: "a6ff544223bf2a7653651ea7f29888a195155c8d", activation_code: "43745d2e79d7aab4dfe2b4a3bd64d8ac577aeafe", remember_token_expires_at: nil, activated_at: nil, deleted_at: nil, state: "pending", created_at: "2009-04-20 20:19:15", updated_at: "2009-04-20 20:19:15"> Looks good so far... But when looking at the database entry, the activation_code actually is NULL! Let''s prove this:>> record.reload=> #<User id: 4, first_name: nil, last_name: nil, login: "quire", email: "quire-hcDgGtZH8xNBDgjK7y7TUQ@public.gmane.org", remember_token: nil, crypted_password: "5670fb5c84b89d64ef405b315e4337304f88dc2b", password_reset_code: nil, salt: "a6ff544223bf2a7653651ea7f29888a195155c8d", activation_code: nil, remember_token_expires_at: nil, activated_at: nil, deleted_at: nil, state: "pending", created_at: "2009-04-20 20:19:15", updated_at: "2009-04-20 20:19:15"> Tadaah! This is a serious bug, isn''t it? The User object only works correct when using "register!" instead of save: josh$ script/console Loading development environment (Rails 2.1.0)>> record = User.new({ :login => ''quire'', :email => ''quire-hcDgGtZH8xNBDgjK7y7TUQ@public.gmane.org'', :password => ''quire'', :password_confirmation => ''quire'' })=> #<User id: nil, first_name: nil, last_name: nil, login: "quire", email: "quire-hcDgGtZH8xNBDgjK7y7TUQ@public.gmane.org", remember_token: nil, crypted_password: nil, password_reset_code: nil, salt: nil, activation_code: nil, remember_token_expires_at: nil, activated_at: nil, deleted_at: nil, state: "passive", created_at: nil, updated_at: nil>>> record.register!=> true>> record.reload=> #<User id: 5, first_name: nil, last_name: nil, login: "quire", email: "quire-hcDgGtZH8xNBDgjK7y7TUQ@public.gmane.org", remember_token: nil, crypted_password: "465f2d6572f47e9adec58022d938b134e570077b", password_reset_code: nil, salt: "293aaa4b1a391f472803767c93c07bf7966e9141", activation_code: "1129116e89f989fee4dccb7eb38946c8e16af93a", remember_token_expires_at: nil, activated_at: nil, deleted_at: nil, state: "pending", created_at: "2009-04-20 20:22:03", updated_at: "2009-04-20 20:22:03"> Can anyone approve this? In my oppinion, save should have exactly the same effect like "register!"... but it definitely doesn''t. Thanks for your opinion. Josh -- Posted via http://www.ruby-forum.com/.
Not sure I understand your problem... event :register do transitions :from => :passive, :to => :pending, :guard => Proc.new {|u| !(u.crypted_password.blank? && u.password.blank?) } end sort of tells me that UsersController#register causes a state transition from :passive to :pending and event :activate do transitions :from => :pending, :to => :active end UsersController#activate causes a state transition from :pending to :active I don''t see any mention of UsersController#save anywhere in either restful_authentication/lib/... or in the controllers and views created using script/generate authenticated User Sessions --options...
Joshua Muheim
2009-Apr-21 09:04 UTC
Re: acts_as_state_machine: bug?! obj.save doesn''t work...
Rick Lloyd wrote:> Not sure I understand your problem... > > I don''t see any mention of UsersController#save anywhere in either > restful_authentication/lib/... or in the controllers and views created > using script/generate authenticated User Sessions --options...The save method is the original ActiveRecord save method. It doesn''t have to do anything with acts_as_state_machine! ;-) Just look at the following to see what I mean: josh$ script/console Loading development environment (Rails 2.1.0)>> record = User.new({ :login => ''quire'', :email => ''quire-hcDgGtZH8xNBDgjK7y7TUQ@public.gmane.org'', :password => ''quire'', :password_confirmation => ''quire'' })=> #<User ... activation_code: nil, state: "passive" ...> # No activation code, state is passive Why is the state passive? In my opinion it should be pending because of this line: acts_as_state_machine :initial => :pending And because in my opinion it should be pending, it should also have an activation code: state :pending, :enter => :make_activation_code However, it doesn''t so far.>> record.save=> true>> record=> #<User ... activation_code: "996b495dcbb15a61cdda19ef5da07a78b27dff87", state: "pending" ... > Well, after calling ActiveRecord''s save method it seems to have changed to the pending state, and the activation_code is available. Looks quite good, so far. In my opinion, the activation_code should now also be saved to the DB. So let''s check this:>> record.reload=> #<User ... activation_code: nil, state: "pending" ... > So here we have the problem! The activation_code is nil again! No idea why, but it''s nil! The only way to get this stuff to work is by calling the "register!" method: josh$ script/console Loading development environment (Rails 2.1.0)>> record = User.new({ :login => ''quire'', :email => ''quire-hcDgGtZH8xNBDgjK7y7TUQ@public.gmane.org'', :password => ''quire'', :password_confirmation => ''quire'' })=> #<User id: nil, first_name: nil, last_name: nil, login: "quire", email: "quire-hcDgGtZH8xNBDgjK7y7TUQ@public.gmane.org", remember_token: nil, crypted_password: nil, password_reset_code: nil, salt: nil, activation_code: nil, remember_token_expires_at: nil, activated_at: nil, deleted_at: nil, state: "passive", created_at: nil, updated_at: nil>>> record.register!=> true>> record=> #<User ... activation_code: "f8395f836ec66c9db966da457ba19cdf5f29dd0a", state: "pending" ... >>> record.reload=> #<User ... activation_code: "d5402915503a0c3f1a9eb984c116bc0ae4c07877", state: "pending" ... > # The activation_code stays now This doesn''t make any sense to me. The only thing that "register!" does is changing the state from "passive" to "pending": event :register do transitions :from => :passive, :to => :pending, :guard => Proc.new {|u| !(u.crypted_password.blank? && u.password.blank?) } end OK, this sounds reasonable, but then I don''t understand, why and where the state is changed when calling save (it''s exactly the same transition from "passive" to "pending" as when calling register!), and why the activation_code gets lost in this case...? Looks everything really strange to me... You see my problem now? -- Posted via http://www.ruby-forum.com/.
Rick Olson
2009-Apr-21 16:25 UTC
Re: acts_as_state_machine: bug?! obj.save doesn''t work...
Perhaps the AASM library is buggy. I haven''t used it in ages, but I seem to recall some issue of it not calling the enter transition unless the event was manually triggered. That''s what the behavior above suggests. If the library is giving you hassles, then generate the authentication code without the aasm flag. This code was submitted to me by someone else, and I don''t have much experience with it. -- Posted via http://www.ruby-forum.com/.
Joshua Muheim
2009-Apr-21 16:28 UTC
Re: acts_as_state_machine: bug?! obj.save doesn''t work...
Rick Olson wrote:> Perhaps the AASM library is buggy. I haven''t used it in ages, but I > seem to recall some issue of it not calling the enter transition unless > the event was manually triggered. That''s what the behavior above > suggests. > > If the library is giving you hassles, then generate the authentication > code without the aasm flag. This code was submitted to me by someone > else, and I don''t have much experience with it.First of all thanks a lot for taking this serious and answering me upon my request, Rick. :-) What do you suggest? Should I try to find the bug in AASM and submit a fix? I don''t like to use workarounds for evidently buggy software... ;-) -- Posted via http://www.ruby-forum.com/.
You might want to look at this a little closer before you submit a bug report. For instance, if you make two changes: 1) FILE: app/controllers/users_controller.rb IN: def create FROM: @user.register! if @user && @user.valid? TO: @user.save! if @user && @user.valid? 2) FILE: vendor/plugins/restful-authentication/lib/authorization/ aasm_roles.rb FROM: aasm_event :register do TO: aasm_event :save do You can now follow the sequence:>> record = User.new({ :login => ''quire'', :email => ''quire-hcDgGtZH8xOIwRZHo2/mJg@public.gmane.orgm'', :password => ''enquire'', :password_confirmation => ''enquire'' })=> #<User id: nil, login: "quire", name: "", email: "quire-hcDgGtZH8xNBDgjK7y7TUQ@public.gmane.org", crypted_password: nil, salt: nil, created_at: nil, updated_at: nil, remember_token: nil, remember_token_expires_at: nil, activation_code: nil, activated_at: nil, state: "passive", deleted_at: nil>>> record.save=> true>> record=> #<User id: nil, login: "quire", name: "", email: "quire-hcDgGtZH8xNBDgjK7y7TUQ@public.gmane.org", crypted_password: nil, salt: nil, created_at: nil, updated_at: nil, remember_token: nil, remember_token_expires_at: nil, activation_code: "8508423584b5c775a60939f9d1966653cd8ea493", activated_at: nil, state: "pending", deleted_at: nil> Of course, you can not actually save record to the database anymore since you''ve masked ActiveRecord''s save method. There''s probably a way to clear that up as well but that''s not your problem here. As far as the "passive" - "pending" issue, I suspect you''re not catching your record early enough in it''s aasm life. These are all good questions to ask the rubyist-aasm folks - I just wouldn''t open the conversation with a !!!BUG REPORT!!! salvo iynwim ;-) On Apr 21, 6:28 am, Joshua Muheim <rails-mailing-l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> RickOlson wrote: > > Perhaps the AASM library is buggy. I haven''t used it in ages, but I > > seem to recall some issue of it not calling the enter transition unless > > the event was manually triggered. That''s what the behavior above > > suggests. > > > If the library is giving you hassles, then generate the authentication > > code without the aasm flag. This code was submitted to me by someone > > else, and I don''t have much experience with it. > > First of all thanks a lot for taking this serious and answering me upon > my request,Rick. :-) > > What do you suggest? Should I try to find the bug in AASM and submit a > fix? I don''t like to use workarounds for evidently buggy software... ;-) > -- > Posted viahttp://www.ruby-forum.com/.
Joshua Muheim
2009-Apr-21 21:59 UTC
Re: acts_as_state_machine: bug?! obj.save doesn''t work...
> You can now follow the sequence: > >>> record = User.new({ :login => ''quire'', :email => ''quire-hcDgGtZH8xNBDgjK7y7TUQ@public.gmane.org'', :password => ''enquire'', :password_confirmation => ''enquire'' }) > => #<User id: nil, login: "quire", name: "", email: > "quire-hcDgGtZH8xNBDgjK7y7TUQ@public.gmane.org", crypted_password: nil, salt: nil, created_at: > nil, updated_at: nil, remember_token: nil, remember_token_expires_at: > nil, activation_code: nil, activated_at: nil, state: "passive", > deleted_at: nil> >>> record.save > => true >>> record > => #<User id: nil, login: "quire", name: "", email: > "quire-hcDgGtZH8xNBDgjK7y7TUQ@public.gmane.org", crypted_password: nil, salt: nil, created_at: > nil, updated_at: nil, remember_token: nil, remember_token_expires_at: > nil, activation_code: "8508423584b5c775a60939f9d1966653cd8ea493", > activated_at: nil, state: "pending", deleted_at: nil>Actually, you forgot to reload the model, because THAT caused the problem... And it seems that we don''t use the same version of the restful_authentication plugin, because mine doesn''t contain a file called aasm_roles.rb; take a look at the attached screen... Attachments: http://www.ruby-forum.com/attachment/3603/restful_authentication.jpg -- Posted via http://www.ruby-forum.com/.
Actually, I didn''t forget. The model wasn''t available for reload because, by masking ActiveRecord#save with UsersController#save, there was nothing to reload. But yes, version is probably going to make any more discussion difficult. Here''s where I go: http://github.com/technoweenie/restful-authentication/tree/master. This site is actively supported, maybe you should move there.> > Actually, you forgot to reload the model, because THAT caused the > problem... > > And it seems that we don''t use the same version of the > restful_authentication plugin, because mine doesn''t contain a file > called aasm_roles.rb; take a look at the attached screen... > > Attachments:http://www.ruby-forum.com/attachment/3603/restful_authentication.jpg > > -- > Posted viahttp://www.ruby-forum.com/.