Marcelo de Moraes Serpa
2010-Jan-27 04:55 UTC
state_machine prevents ActiveRecord from being persisted
Hello list, I have a subscription model that has a upgrade event. This changes the state from free->paying and triggers a charge method in the subscription model. This charge method then creates a new instance of the payment model (just in memory, using .new), and triggers the pay event on it. The pay event tries to transition the payment from pending to paid and calls the do_pay method before the transition (before_transition). Everything would be 100% if it weren''t for a small details. The payment should be persisted even if the subscription transition from free->paying has failed. In the do_pay method, if the payment failed, I do self.decline (a FSM event that simply changes from pending->declined) and I have an after_transition callback setup like: "after_transition any => any, do {|p| p.save }" which gets triggered. However, since I return false in the do_pay method to prevent the pendign->paid transition to complete (the payment failed, remember?), state_machine then rollbacks the payment''s save. What I did was to call: self.class.connection.commit_db_transaction after self.decline and before return false in the payment''s do_pay method. This works, but is kind of ugly. If anyone out there has any suggestions on how I could improve this design or maybe just tell me that this is ok to do, alleviating my worries about what seems to be a hack, I would be grateful! Thanks, Marcelo. -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Joel Dezenzio
2010-Jan-27 15:09 UTC
RE: state_machine prevents ActiveRecord from being persisted
What type of payment system are you using? IPN? If so, then once the payment reaches the payment gateway and the customer finishes paying, you check the status of the payment received and if successful, you change the subscription based off the amount(s) received. You are supplying information but you aren''t supplying any actual methods so that we can review what you are doing. I use an IPN system for one of my sites and do the above. I''d love to help you out but without seeing code and how things are actually working with your controllers/models, I can''t. Sincerely, Joel Dezenzio Website Bio: http://jdezenzio.com/ Rails Production Sites: http://ncaastatpages.com -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Marcelo de Moraes Serpa
2010-Jan-28 20:06 UTC
Re: state_machine prevents ActiveRecord from being persisted
Hi Joel, thanks for the reply. The system is working well. My problem is with the state_machine gem. If the payment fails, I can''t really get it saved without doing the hack I mentioned, becase the state_machine implementation rollback any db transaction when you return false from an event, however, I have to return false to tell the subscription object that the payment has failed, hence, the subscription upgrade fails, and state_machine rollback. It has been solved (with that hack) but I just wanted to know if there was a more elegant non-hackish way to do that with state_machine. Regards, Marcelo. On Wed, Jan 27, 2010 at 9:09 AM, Joel Dezenzio <jdezenzio-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> What type of payment system are you using? IPN? > > If so, then once the payment reaches the payment gateway and the customer > finishes paying, you check the status of the payment received and if > successful, you change the subscription based off the amount(s) received. > You are supplying information but you aren''t supplying any actual methods > so > that we can review what you are doing. I use an IPN system for one of my > sites and do the above. I''d love to help you out but without seeing code > and how things are actually working with your controllers/models, I can''t. > > Sincerely, > > Joel Dezenzio > Website Bio: http://jdezenzio.com/ > Rails Production Sites: http://ncaastatpages.com > > -- > You received this message because you are subscribed to the Google Groups > "Ruby on Rails: Talk" group. > To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org > To unsubscribe from this group, send email to > rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org<rubyonrails-talk%2Bunsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org> > . > For more options, visit this group at > http://groups.google.com/group/rubyonrails-talk?hl=en. > >-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
climber
2013-Dec-03 13:55 UTC
Re: state_machine prevents ActiveRecord from being persisted
Hello, I also has this problem, I need to create an AuditTrail instance in db even if the transition is failed, but if the transition failed, the transaction is rollback, and the failed AuditTrail instance is not created in database. On Wednesday, January 27, 2010 12:55:46 PM UTC+8, FFighter wrote:> > Hello list, > > I have a subscription model that has a upgrade event. This changes the > state from free->paying and triggers a charge method in the subscription > model. This charge method then creates a new instance of the payment model > (just in memory, using .new), and triggers the pay event on it. The pay > event tries to transition the payment from pending to paid and calls the > do_pay method before the transition (before_transition). > > Everything would be 100% if it weren''t for a small details. The payment > should be persisted even if the subscription transition from free->paying > has failed. In the do_pay method, if the payment failed, I do self.decline > (a FSM event that simply changes from pending->declined) and I have an > after_transition callback setup like: "after_transition any => any, do > {|p| p.save }" which gets triggered. However, since I return false in the > do_pay method to prevent the pendign->paid transition to complete (the > payment failed, remember?), state_machine then rollbacks the payment''s > save. > > What I did was to call: > > self.class.connection.commit_db_transaction > > after self.decline and before return false in the payment''s do_pay method. > This works, but is kind of ugly. > > If anyone out there has any suggestions on how I could improve this design > or maybe just tell me that this is ok to do, alleviating my worries about > what seems to be a hack, I would be grateful! > > Thanks, > > Marcelo. >-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To view this discussion on the web visit https://groups.google.com/d/msgid/rubyonrails-talk/94d1b4b4-f7e2-413e-baf2-e13d55138e3d%40googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
It sounds like you''re in a tangle between FSM states and ActiveRecord states. You might need to add a payment_queued state that forces an AR save before transitioning to do_pay. You could then add some logic that fires a loop back to through do_pay (retry n times after increasing timeout) before failing. On Thursday, January 28, 2010 3:06:47 PM UTC-5, FFighter wrote:> > Hi Joel, thanks for the reply. > > The system is working well. My problem is with the state_machine gem. If > the payment fails, I can''t really get it saved without doing the hack I > mentioned, becase the state_machine implementation rollback any db > transaction when you return false from an event, however, I have to return > false to tell the subscription object that the payment has failed, hence, > the subscription upgrade fails, and state_machine rollback. > > It has been solved (with that hack) but I just wanted to know if there > was a more elegant non-hackish way to do that with state_machine. > > Regards, > > Marcelo. > > On Wed, Jan 27, 2010 at 9:09 AM, Joel Dezenzio <jdez...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org<javascript:> > > wrote: > >> What type of payment system are you using? IPN? >> >> If so, then once the payment reaches the payment gateway and the customer >> finishes paying, you check the status of the payment received and if >> successful, you change the subscription based off the amount(s) received. >> You are supplying information but you aren''t supplying any actual methods >> so >> that we can review what you are doing. I use an IPN system for one of my >> sites and do the above. I''d love to help you out but without seeing code >> and how things are actually working with your controllers/models, I can''t. >> >> Sincerely, >> >> Joel Dezenzio >> Website Bio: http://jdezenzio.com/ >> Rails Production Sites: http://ncaastatpages.com >> >> -- >> You received this message because you are subscribed to the Google Groups >> "Ruby on Rails: Talk" group. >> To post to this group, send email to rubyonra...-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org<javascript:> >> . >> To unsubscribe from this group, send email to >> rubyonrails-ta...-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org <javascript:>. >> For more options, visit this group at >> http://groups.google.com/group/rubyonrails-talk?hl=en. >> >> >-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To view this discussion on the web visit https://groups.google.com/d/msgid/rubyonrails-talk/9aa88aa9-4b2a-4c11-b45c-45b9bcdd9478%40googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.