Phoenix Rising
2010-Apr-13 20:40 UTC
[Rails 2.3] Adding a "phase" to the ActiveRecord Lifecycle
I''ve run into a situation where it seems to me that if I could "extend" the typical AR lifecycle to add another "phase" or step to it, it would simplify things. My problem is that I just don''t know how to do that, and I haven''t been able to find documentation anywhere on it! I''m working on an e-commerce application that''s somewhat complex. Due to constraints of the organization, I can''t have accounts or authentication. My theoretical approach is to store an "order ID" in a user''s session, and of course all selects/updates etc. will be only for that ID from their session, thus keeping the current status of the order in the database at all times. If it were something simple I''d just store an array of object IDs in the user''s session, but there are several different kinds of products/services to buy, each with vastly different models and various requirements ("if you have this you must have that but MUST NOT have this", etc.). The AR lifecycle question comes into play because I''d like to add some form of validation on the Order model, but ONLY before and after the user''s card is charged. So here''s a simple example - Order < ActiveRecord::Base belongs_to :object has_many :item_joins has_many :items, :through => :item_joins has_many :other_item_joins has_many :other_items, :through => :other_item_joins # ... and so on ... end Because the user can add multiple items and other items to their order, as well as set the "object" on their order at any point in the ordering process, I can''t call the validations I want after save. I''d much rather have a before/after "card_charged" step in the lifecycle, and run a validation before the card is charged, then one after it''s charged. So, for example, I''d like to be able to do something like: Order < ActiveRecord::Base # ...associations as above... before_charged :ensure_not_empty private def ensure_not_empty if self.items.count < 1 and self.other_items.count < 1 errors.add_to_base("Your order is empty!") return false end end And this would need to fire when Order#charge_card (or similarly named method) is called, canceling the call to Order#charge_card if false is returned. I took a quick look at state machines (aasm), and I have to confess that I don''t know much about a state machine or how one works other than very basic theory. It seems like it might be overkill to me, when all I want to do is add two methods to the lifecycle as above. However, I''m fully willing to consider the possibility that what I''m suggesting here is outside the realm of best practices. Any ideas as to how I could add these steps to the lifecycle of just this object? -- 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.
Michael Schuerig
2010-Apr-14 11:59 UTC
Re: [Rails 2.3] Adding a "phase" to the ActiveRecord Lifecycle
On Tuesday 13 April 2010, Phoenix Rising wrote:> Because the user can add multiple items and other items to their > order, as well as set the "object" on their order at any point in the > ordering process, I can''t call the validations I want after > save. I''d much rather have a before/after "card_charged" step in > the lifecycle, and run a validation before the card is charged, then > one after it''s charged.I think the best way would be to use a state machine, as you indicated yourself in a paragraph I snipped. Second best would be to use conditional validations, see the :if and :unless options on all the validates_something methods. Michael -- Michael Schuerig mailto:michael-q5aiKMLteq4b1SvskN2V4Q@public.gmane.org http://www.schuerig.de/michael/ -- 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.