Hey guys, I''m having a hard time w/ the after_update callback on rails... As far as I can tell, when I define a after_update callback on a model, the attributes of the object have the same values that they had *before* Base.save was called. I''m probably wrong so here''s the code: UNIT TEST: def test_register_item_adjusts_account_balance account = accounts(:cams_credit_card) transaction = RegisterItem.new(:date => ''2006-10-31'', :description => ''Chinese food'', :amount => ''-13.44'') transaction.account = account transaction.save assert_equal -113.44, account.balance #this assertion passes transaction.amount = -15.50 transaction.save assert_equal -115.50, account.balance # FAILS transaction.destroy assert_equal -100.00, account.balance #this assertion will pass end FAILURE OUTPUT: Loaded suite test/unit/register_item_test Started .F. Finished in 0.202591 seconds. 1) Failure: test_register_item_adjusts_account_balance(RegisterItemTest) [test/unit/register_item_test.rb:31]: <-115.5> expected but was <-113.44>. 3 tests, 6 assertions, 1 failures, 0 errors So changing the amount on a transaction (RegisterItem) should change the current balance of an account. Here''s the relevent callbacks: REGISTER_ITEM UPDATE CALLBACKS: def before_update account.balance -= amount account.save end def after_update account.balance += amount account.save end So the idea is that before the transaction is updated i subtract the amount of the transaction back from the account, and then add the new amount back on. It looks like @amount is still the old value during the after_update callback though. is that correct? how can i access the new value? Thanks, Cameron Matheson --~--~---------~--~----~------------~-------~--~----~ 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-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
the steps are: before_update [update operation] after_update so to keep things simple, say your account balance is 0.0: ... # existing transaction transaction.amount = 10.0 # transaction.account.balance = 0.0 still transaction.save # before_update: transaction.amount = 10.0, transaction.account.balance = -10.0 # update operation # after_update: transaction.amount = 10.0, transaction.account.balance = 0.0 so you''re back where you started, which is what your test is telling you. On 1/4/07, Cam <cameron.matheson-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> > Hey guys, > > I''m having a hard time w/ the after_update callback on rails... As > far as I can tell, when I define a after_update callback on a model, > the attributes of the object have the same values that they had > *before* Base.save was called. I''m probably wrong so here''s the code: > > UNIT TEST: > def test_register_item_adjusts_account_balance > account = accounts(:cams_credit_card) > transaction = RegisterItem.new(:date => ''2006-10-31'', > :description => ''Chinese food'', > :amount => ''-13.44'') > transaction.account = account > transaction.save > assert_equal -113.44, account.balance #this assertion passes > > transaction.amount = -15.50 > transaction.save > assert_equal -115.50, account.balance # FAILS > > transaction.destroy > assert_equal -100.00, account.balance #this assertion will pass > end > > FAILURE OUTPUT: > Loaded suite test/unit/register_item_test > Started > .F. > Finished in 0.202591 seconds. > > 1) Failure: > test_register_item_adjusts_account_balance(RegisterItemTest) > [test/unit/register_item_test.rb:31]: > <-115.5> expected but was > <-113.44>. > > 3 tests, 6 assertions, 1 failures, 0 errors > > > So changing the amount on a transaction (RegisterItem) should change > the current balance of an account. Here''s the relevent callbacks: > > REGISTER_ITEM UPDATE CALLBACKS: > def before_update > account.balance -= amount > account.save > end > > def after_update > account.balance += amount > account.save > end > > So the idea is that before the transaction is updated i subtract the > amount of the transaction back from the account, and then add the new > amount back on. It looks like @amount is still the old value during > the after_update callback though. is that correct? how can i access > the new value? > > Thanks, > Cameron Matheson > > > >--~--~---------~--~----~------------~-------~--~----~ 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-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Would calling account.reload after the save cause problems for you elsewhere? Cameron Matheson wrote:> Hey guys, > > I''m having a hard time w/ the after_update callback on rails... As > far as I can tell, when I define a after_update callback on a model, > the attributes of the object have the same values that they had > *before* Base.save was called. I''m probably wrong so here''s the code:.... <snip>> Here''s the relevent callbacks: > > REGISTER_ITEM UPDATE CALLBACKS: > def before_update > account.balance -= amount > account.save > end > > def after_update > account.balance += amount > account.save > end-- Posted via http://www.ruby-forum.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-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Hey thanks for the response: On 1/4/07, Chris Hall <christopher.k.hall-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> so to keep things simple, say your account balance is 0.0:> ... > # existing transaction > transaction.amount = 10.0 # transaction.account.balance = 0.0 still > > transaction.save > # before_update: transaction.amount = 10.0, > transaction.account.balance = -10.0 > # update operation > # after_update: transaction.amount = 10.0, transaction.account.balance = 0.0 > > so you''re back where you started, which is what your test is telling you.Ok so there is a problem in the way i understand the before_update callback, or in your logic (probably my problem which would explain the bug). Anyway, this is a before/after_*update* callback, it looks like the scenario you''re describing is a before/after_*create* kind of deal. so the way i would understand it would be like so: #account.balance == 0 transaction.amount = 10.0 #transaction.amount formerly == 0 before_update: transaction.amount -= 0\ after_update: transaction.amount += 10 # account.balance == 10 is that wrong? Cameron Matheson --~--~---------~--~----~------------~-------~--~----~ 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-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Hey Steve, On 1/4/07, Steve Koppelman <rails-mailing-list-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> > Would calling account.reload after the save cause problems for you > elsewhere? >I wasn''t aware of the reload method. I called it after save and although it didn''t cause any problems, it didn''t change the behavior of the program either (unless i called self.reload on the transaction, in which case it looks like the after_update callback didn''t get called) Thanks! Cam --~--~---------~--~----~------------~-------~--~----~ 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-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
these are the callbacks that are run during an update operation before_validation before_validation_on_update after_validation after_validation_on_update before_save before_update <UPDATE OPERATION> after_update after_save if you are creating a new record, replace *_update with *_create in the above list. thats the difference. so, knowing this, we see that your before and after updates will run around the update operation. # transaction.account.balance = -100.00 transaction.amount = -15.50 transaction.save # before_update, update, after_update # before_update callback # ----------------------------------- # account.balance -= amount # -100.00 - (-15.50) = -(100.00 - 15.50) = -84.50 # account.save # # transaction update operation # # after_update callback # -------------------------------- # account.balance += amount # -84.50 + (-15.50) = -(84.50 + 15.50) = -100.00 # account.save # assert_equal -115.50, account.balance # FAILS <start before_update> account.balance -= amount # 113.44, as 100.00 - (-13.44) = 100.00 + 13.44 = 113.44 account.save # balance of 113.44 is saved to db <end before_update> <transaction update operation> <start after_update> account.balance += amount # 100.00, as 113.44 + (-13.44) = 113.44 - 13.44 = 100.00 account.save # balance of 100.00 is saved to the db <end after_update> and so you are right back where you started as far as your account.balance goes, which is exactly what your test is telling you. follow? Chris On 1/4/07, Cam <cameron.matheson-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> > Hey thanks for the response: > > On 1/4/07, Chris Hall <christopher.k.hall-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > so to keep things simple, say your account balance is 0.0: > > > ... > > # existing transaction > > transaction.amount = 10.0 # transaction.account.balance = 0.0 still > > > > transaction.save > > # before_update: transaction.amount = 10.0, > > transaction.account.balance = -10.0 > > # update operation > > # after_update: transaction.amount = 10.0, transaction.account.balance = 0.0 > > > > so you''re back where you started, which is what your test is telling you. > > Ok so there is a problem in the way i understand the before_update > callback, or in your logic (probably my problem which would explain > the bug). Anyway, this is a before/after_*update* callback, it looks > like the scenario you''re describing is a before/after_*create* kind of > deal. so the way i would understand it would be like so: > > #account.balance == 0 > transaction.amount = 10.0 #transaction.amount formerly == 0 > before_update: transaction.amount -= 0\ > after_update: transaction.amount += 10 > # account.balance == 10 > > is that wrong? > Cameron Matheson > > > >--~--~---------~--~----~------------~-------~--~----~ 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-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
hey, On 1/16/07, Chris Hall <christopher.k.hall-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> follow?it makes sense... i hadn''t understood how it worked previously. i figured that since it was before save was called, that the data would have been the old data. so is there no way to access the previous data w/ callbacks? i guess i could store the old amount in all of the RegisterItem model, but i''d rather not go that route. thanks, cam --~--~---------~--~----~------------~-------~--~----~ 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-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---